diff --git a/Projects/tinyK20_SolderDispenser/.gitignore b/Projects/tinyK20_SolderDispenser/.gitignore index 2833401..09ec1fd 100644 --- a/Projects/tinyK20_SolderDispenser/.gitignore +++ b/Projects/tinyK20_SolderDispenser/.gitignore @@ -1,5 +1,5 @@ /Debug/ -/Generated_Code/ +# /Generated_Code/ /.settings/ /Documentation/ *.g_c diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/.gdbinit-FreeRTOS-helpers b/Projects/tinyK20_SolderDispenser/Generated_Code/.gdbinit-FreeRTOS-helpers new file mode 100644 index 0000000..8718d5a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/.gdbinit-FreeRTOS-helpers @@ -0,0 +1,155 @@ +################################################################################# +# .gdbinit-FreeRTOS-helpers +# +# Created on: 29.03.2013 +# Author: Artem Pisarenko +# +# Helper script providing support for FreeRTOS-aware debugging +# Supported architectures: Cortex-M3 +# Features: +# - showing tasks (handle and name); +# - switching context to specified task from almost any context (excluding system exceptions); +# - restore current running context. +################################################################################# + +# Command "freertos_show_threads" +# Shows tasks table: handle(xTaskHandle) and name +define freertos_show_threads + set $thread_list_size = 0 + set $thread_list_size = uxCurrentNumberOfTasks + if ($thread_list_size == 0) + echo FreeRTOS missing or scheduler isn't started\n + else + set $current_thread = pxCurrentTCB + set $tasks_found = 0 + set $idx = 0 + + set $task_list = pxReadyTasksLists + set $task_list_size = sizeof(pxReadyTasksLists)/sizeof(pxReadyTasksLists[0]) + while ($idx < $task_list_size) + _freertos_show_thread_item $task_list[$idx] + set $idx = $idx + 1 + end + + _freertos_show_thread_item xDelayedTaskList1 + _freertos_show_thread_item xDelayedTaskList2 + _freertos_show_thread_item xPendingReadyList + + set $VAL_dbgFreeRTOSConfig_suspend = dbgFreeRTOSConfig_suspend_value + if ($VAL_dbgFreeRTOSConfig_suspend != 0) + _freertos_show_thread_item xSuspendedTaskList + end + + set $VAL_dbgFreeRTOSConfig_delete = dbgFreeRTOSConfig_delete_value + if ($VAL_dbgFreeRTOSConfig_delete != 0) + _freertos_show_thread_item xTasksWaitingTermination + end + end +end + +# Command "freertos_switch_to_task" +# Switches debugging context to specified task, argument - task handle +define freertos_switch_to_task + set var dbgPendingTaskHandle = $arg0 + set $current_IPSR_val = $xpsr & 0xFF + if (($current_IPSR_val >= 1) && ($current_IPSR_val <= 15)) + echo Switching from system exception context isn't supported + else + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + set $last_PRIMASK_val = $PRIMASK + set $last_SCB_ICSR_val = *((volatile unsigned long *)0xE000ED04) + set $last_SYSPRI2_val = *((volatile unsigned long *)0xE000ED20) + set $last_SCB_CCR_val = *((volatile unsigned long *)0xE000ED14) + set $running_IPSR_val = $current_IPSR_val + set $PRIMASK = 0 + # *(portNVIC_SYSPRI2) &= ~(255 << 16) // temporary increase PendSV priority to highest + set {unsigned int}0xe000ed20 = ($last_SYSPRI2_val & (~(255 << 16))) + # set SCB->CCR NONBASETHRDENA bit (allows processor enter thread mode from at any execution priority level) + set {unsigned int}0xE000ED14 = (1) | $last_SCB_CCR_val + set var dbgPendSVHookState = 1 + end + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + stepi + stepi + # here we get rewound to task + end +end + +# Command "freertos_restore_running_context" +# Restores context of running task +define freertos_restore_running_context + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + echo Current task is RUNNING, ignoring command... + else + set var dbgPendingTaskHandle = (void *)pxCurrentTCB + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # check what execution mode was in context we started to switch from + if ($running_IPSR_val == 0) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + else + # force returning to handler mode + set $lr = 0xFFFFFFF1 + end + stepi + stepi + # here we get rewound to running task at place we started switching + # restore processor state + set $PRIMASK = $last_PRIMASK_val + set {unsigned int}0xe000ed20 = $last_SYSPRI2_val + set {unsigned int}0xE000ED14 = $last_SCB_CCR_val + if ($last_SCB_ICSR_val & (1 << 28)) + set {unsigned int}0xe000ed04 = 0x10000000 + end + set var dbgPendSVHookState = 0 + end +end + +# Command "show_broken_backtrace" +# Workaround of issue when context is being stuck in the middle of function epilogue (i.e., in vTaskDelay()) +# This solution is applied to following situation only: +### ... function body end +### xxxxxxxx+0: add.w r7, r7, #16 +### xxxxxxxx+4: mov sp, r7 ; <- debug current instruction pointer +### xxxxxxxx+6: pop {r7, pc} +### } +# (Otherwise it will crash !) +define show_broken_backtrace + # cancel effect of xxxxxxxx+4 instruction twice (because we will step it to update eclipse views) + set $r7 = $r7 - 16 - 16 + set $pc = $pc - 4 + stepi +end + + +####################### +# Internal functions +define _freertos_show_thread_item + set $list_thread_count = $arg0.uxNumberOfItems + set $prev_list_elem_ptr = -1 + set $list_elem_ptr = $arg0.xListEnd.pxPrevious + while (($list_thread_count > 0) && ($list_elem_ptr != 0) && ($list_elem_ptr != $prev_list_elem_ptr) && ($tasks_found < $thread_list_size)) + set $threadid = $list_elem_ptr->pvOwner + set $thread_name_str = (*((tskTCB *)$threadid)).pcTaskName + set $tasks_found = $tasks_found + 1 + set $list_thread_count = $list_thread_count - 1 + set $prev_list_elem_ptr = $list_elem_ptr + set $list_elem_ptr = $prev_list_elem_ptr->pxPrevious + if ($threadid == $current_thread) + printf "0x%x\t%s\t\t<---RUNNING\n", $threadid, $thread_name_str + else + printf "0x%x\t%s\n", $threadid, $thread_name_str + end + end +end + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.c new file mode 100644 index 0000000..fdf751d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.c @@ -0,0 +1,252 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +/* MODULE BitIoLdd1. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd1_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd1_TDeviceData *BitIoLdd1_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd1_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=0x10 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x10); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~0x10 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x10)); + /* Initialization of Port Control register */ + /* PORTD_PCR4: ISF=0,MUX=1 */ + PORTD_PCR4 = (uint32_t)((PORTD_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd1_MODULE_BASE_ADDRESS) & BitIoLdd1_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_TogglePortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.h new file mode 100644 index 0000000..20d41cf --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd1.h @@ -0,0 +1,236 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +#ifndef __BitIoLdd1_H +#define __BitIoLdd1_H + +/* MODULE BitIoLdd1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd1_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd1_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd1_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_NegVal_METHOD_ENABLED /*!< NegVal method of the component BitIoLdd1 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd1_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORT_MASK 0x10U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.c new file mode 100644 index 0000000..fb97f65 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.c @@ -0,0 +1,287 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd2.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd2 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd2_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd2_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd2_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd2_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd2.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd2_module BitIoLdd2 module documentation +** @{ +*/ + +/* MODULE BitIoLdd2. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd2_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd2_TDeviceData *BitIoLdd2_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd2_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd2_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=1 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x01); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~1 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x01)); + /* Initialization of Port Control register */ + /* PORTD_PCR0: ISF=0,MUX=1 */ + PORTD_PCR0 = (uint32_t)((PORTD_PCR0 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd2_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd2_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd2_MODULE_BASE_ADDRESS) & BitIoLdd2_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd2_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd2_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd2_MODULE_BASE_ADDRESS, BitIoLdd2_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd2_MODULE_BASE_ADDRESS, BitIoLdd2_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd2_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd2_MODULE_BASE_ADDRESS, BitIoLdd2_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd2_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd2_MODULE_BASE_ADDRESS, BitIoLdd2_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd2_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_NegVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_TogglePortDataOutputMask(BitIoLdd2_MODULE_BASE_ADDRESS, BitIoLdd2_PORT_MASK); +} + +/* END BitIoLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.h new file mode 100644 index 0000000..d55864a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd2.h @@ -0,0 +1,264 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd2.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd2 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd2_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd2_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd2_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd2_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd2.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd2_module BitIoLdd2 module documentation +** @{ +*/ + +#ifndef __BitIoLdd2_H +#define __BitIoLdd2_H + +/* MODULE BitIoLdd2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd2_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd2_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd2_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd2_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_NegVal_METHOD_ENABLED /*!< NegVal method of the component BitIoLdd2 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd2_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd2_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd2_PORT_MASK 0x01U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd2_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd2_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd2_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd2_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd2_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd2_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd2_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd2_NegVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.c new file mode 100644 index 0000000..22927fc --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd4.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd4 +** Pin for I/O : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd4_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd4_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd4_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd4.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd4_module BitIoLdd4 module documentation +** @{ +*/ + +/* MODULE BitIoLdd4. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd4_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd4_TDeviceData *BitIoLdd4_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd4_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd4_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd4_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=2 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x02); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~2 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x02)); + /* Initialization of Port Control register */ + /* PORTD_PCR1: ISF=0,MUX=1 */ + PORTD_PCR1 = (uint32_t)((PORTD_PCR1 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd4_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd4_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd4_MODULE_BASE_ADDRESS) & BitIoLdd4_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd4_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd4_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd4_MODULE_BASE_ADDRESS, BitIoLdd4_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd4_MODULE_BASE_ADDRESS, BitIoLdd4_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd4_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd4_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd4_MODULE_BASE_ADDRESS, BitIoLdd4_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd4_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd4_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd4_MODULE_BASE_ADDRESS, BitIoLdd4_PORT_MASK); +} + +/* END BitIoLdd4. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.h new file mode 100644 index 0000000..3825e11 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd4.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd4.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd4 +** Pin for I/O : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd4_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd4_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd4_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd4.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd4_module BitIoLdd4 module documentation +** @{ +*/ + +#ifndef __BitIoLdd4_H +#define __BitIoLdd4_H + +/* MODULE BitIoLdd4. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd4_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd4_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd4_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd4_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd4 is enabled (generated) */ +#define BitIoLdd4_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd4 is enabled (generated) */ +#define BitIoLdd4_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd4 is enabled (generated) */ +#define BitIoLdd4_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd4 is enabled (generated) */ +#define BitIoLdd4_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd4 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd4_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd4_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd4_PORT_MASK 0x02U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd4_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd4_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd4_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd4_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd4_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd4_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd4_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd4_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd4. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd4_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.c new file mode 100644 index 0000000..2d784a5 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd5.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd5 +** Pin for I/O : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd5_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd5_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd5_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd5.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd5_module BitIoLdd5 module documentation +** @{ +*/ + +/* MODULE BitIoLdd5. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd5.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd5_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd5_TDeviceData *BitIoLdd5_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd5_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd5_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd5_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=4 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x04); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~4 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x04)); + /* Initialization of Port Control register */ + /* PORTD_PCR2: ISF=0,MUX=1 */ + PORTD_PCR2 = (uint32_t)((PORTD_PCR2 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd5_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd5_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd5_MODULE_BASE_ADDRESS) & BitIoLdd5_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd5_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd5_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd5_MODULE_BASE_ADDRESS, BitIoLdd5_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd5_MODULE_BASE_ADDRESS, BitIoLdd5_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd5_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd5_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd5_MODULE_BASE_ADDRESS, BitIoLdd5_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd5_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd5_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd5_MODULE_BASE_ADDRESS, BitIoLdd5_PORT_MASK); +} + +/* END BitIoLdd5. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.h new file mode 100644 index 0000000..3978b03 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd5.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd5.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd5 +** Pin for I/O : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd5_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd5_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd5_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd5.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd5_module BitIoLdd5 module documentation +** @{ +*/ + +#ifndef __BitIoLdd5_H +#define __BitIoLdd5_H + +/* MODULE BitIoLdd5. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd5_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd5_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd5_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd5_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd5 is enabled (generated) */ +#define BitIoLdd5_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd5 is enabled (generated) */ +#define BitIoLdd5_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd5 is enabled (generated) */ +#define BitIoLdd5_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd5 is enabled (generated) */ +#define BitIoLdd5_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd5 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd5_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd5_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd5_PORT_MASK 0x04U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd5_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd5_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd5_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd5_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd5_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd5_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd5_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd5_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd5. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd5_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.c new file mode 100644 index 0000000..f555027 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd6.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd6 +** Pin for I/O : PTD3/SPI0_SIN/UART2_TX +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd6.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd6_module BitIoLdd6 module documentation +** @{ +*/ + +/* MODULE BitIoLdd6. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd6_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd6_TDeviceData *BitIoLdd6_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd6_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd6_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd6_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=8 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x08); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~8 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x08)); + /* Initialization of Port Control register */ + /* PORTD_PCR3: ISF=0,MUX=1 */ + PORTD_PCR3 = (uint32_t)((PORTD_PCR3 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd6_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd6_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd6_MODULE_BASE_ADDRESS) & BitIoLdd6_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd6_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd6_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd6_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); +} + +/* END BitIoLdd6. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.h new file mode 100644 index 0000000..e34aeae --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd6.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd6.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd6 +** Pin for I/O : PTD3/SPI0_SIN/UART2_TX +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd6.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd6_module BitIoLdd6 module documentation +** @{ +*/ + +#ifndef __BitIoLdd6_H +#define __BitIoLdd6_H + +/* MODULE BitIoLdd6. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd6_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd6_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd6_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd6_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd6 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd6_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd6_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd6_PORT_MASK 0x08U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd6_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd6_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd6. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd6_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.c new file mode 100644 index 0000000..b02049a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd7.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd7 +** Pin for I/O : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd7.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd7_module BitIoLdd7 module documentation +** @{ +*/ + +/* MODULE BitIoLdd7. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd7.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd7_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd7_TDeviceData *BitIoLdd7_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd7_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd7_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd7_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=0x80 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x80); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~0x80 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x80)); + /* Initialization of Port Control register */ + /* PORTD_PCR7: ISF=0,MUX=1 */ + PORTD_PCR7 = (uint32_t)((PORTD_PCR7 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd7_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd7_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd7_MODULE_BASE_ADDRESS) & BitIoLdd7_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd7_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd7_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd7_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); +} + +/* END BitIoLdd7. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.h new file mode 100644 index 0000000..86d4c11 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd7.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd7.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd7 +** Pin for I/O : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd7.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd7_module BitIoLdd7 module documentation +** @{ +*/ + +#ifndef __BitIoLdd7_H +#define __BitIoLdd7_H + +/* MODULE BitIoLdd7. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd7_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd7_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd7_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd7_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd7 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd7_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd7_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd7_PORT_MASK 0x80U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd7_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd7_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd7. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd7_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.c new file mode 100644 index 0000000..b746db0 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd8.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd8 +** Pin for I/O : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd8.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd8_module BitIoLdd8 module documentation +** @{ +*/ + +/* MODULE BitIoLdd8. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd8.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd8_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd8_TDeviceData *BitIoLdd8_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd8_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd8_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd8_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=0x40 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x40); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~0x40 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x40)); + /* Initialization of Port Control register */ + /* PORTD_PCR6: ISF=0,MUX=1 */ + PORTD_PCR6 = (uint32_t)((PORTD_PCR6 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd8_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd8_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd8_MODULE_BASE_ADDRESS) & BitIoLdd8_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd8_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd8_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd8_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); +} + +/* END BitIoLdd8. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.h new file mode 100644 index 0000000..718f401 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd8.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd8.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd8 +** Pin for I/O : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd8.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd8_module BitIoLdd8 module documentation +** @{ +*/ + +#ifndef __BitIoLdd8_H +#define __BitIoLdd8_H + +/* MODULE BitIoLdd8. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd8_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd8_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd8_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd8_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd8 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd8_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd8_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd8_PORT_MASK 0x40U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd8_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd8_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd8. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd8_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.c b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.c new file mode 100644 index 0000000..22aafc8 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.c @@ -0,0 +1,186 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd9.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd9 +** Pin for I/O : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/EWM_OUT_b +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd9.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd9_module BitIoLdd9 module documentation +** @{ +*/ + +/* MODULE BitIoLdd9. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd9.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd9_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd9_TDeviceData *BitIoLdd9_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd9_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd9_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd9_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as input */ + /* GPIOD_PDDR: PDD&=~0x20 */ + GPIOD_PDDR &= (uint32_t)~(uint32_t)(GPIO_PDDR_PDD(0x20)); + /* Initialization of Port Control register */ + /* PORTD_PCR5: ISF=0,MUX=1 */ + PORTD_PCR5 = (uint32_t)((PORTD_PCR5 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd9_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd9_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataInput(BitIoLdd9_MODULE_BASE_ADDRESS) & BitIoLdd9_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* END BitIoLdd9. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.h b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.h new file mode 100644 index 0000000..1e4247d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/BitIoLdd9.h @@ -0,0 +1,182 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd9.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd9 +** Pin for I/O : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/EWM_OUT_b +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd9.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd9_module BitIoLdd9 module documentation +** @{ +*/ + +#ifndef __BitIoLdd9_H +#define __BitIoLdd9_H + +/* MODULE BitIoLdd9. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd9_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd9_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd9_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd9_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd9 is enabled (generated) */ +#define BitIoLdd9_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd9 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd9_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd9_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd9_PORT_MASK 0x20U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd9_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd9_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd9. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd9_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.c new file mode 100644 index 0000000..aa811e4 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.c @@ -0,0 +1,770 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CDC1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FSL_USB_CDC_Device +** Version : Component 01.103, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : CDC1 +** Shell : CLS1 +** CPU : Kinetis K20D50 +** CDC Settings : Enabled +** .inf ClassGuid : 4D36E978-E325-11CE-BFC1-08002BE10318 +** .inf VID : 0x2504 +** .inf PID : 0x0300 +** .inf PRVDR : Freescale +** .inf MFGNAME : My Company +** .inf DESCRIPTION : Freescale CDC Device +** .inf SERVICE : Virtual Com Driver +** Bus reported device : FSL CDC DEVICE +** Bus reported vendor : FREESCALE INC. +** Serial Number : 000123ABC +** Device Subclass : 0 +** Configuration : +** USB_EP0_SIZE (in) : 32 +** USB_EP1_SIZE (out) : 32 +** USB_EP2_SIZE (notify) : 32 +** Send Buffer : RingBuffer +** Receive Buffer : RingBuffer +** SendDataBlock : +** Use Timeout : Enabled +** Timeout : TMOUT1 +** App Task Timeout (ms) : 20 +** Waiting time (ms) : 10 +** Wait : WAIT1 +** Power Options : +** Bus Powered : yes +** Self Powered : yes +** Current Draw (mA) : 100 +** Contents : +** ClearRxBuffer - void CDC1_ClearRxBuffer(void); +** ClearTxBuffer - void CDC1_ClearTxBuffer(void); +** GetFreeInTxBuf - uint16_t CDC1_GetFreeInTxBuf(void); +** GetCharsInTxBuf - uint16_t CDC1_GetCharsInTxBuf(void); +** GetCharsInRxBuf - uint16_t CDC1_GetCharsInRxBuf(void); +** GetChar - uint8_t CDC1_GetChar(CDC1_TComData *Chr); +** RecvChar - uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +** SendChar - uint8_t CDC1_SendChar(CDC1_TComData Chr); +** SendString - uint8_t CDC1_SendString(CDC1_TComData *Chr); +** SendBlock - uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +** PutBufferChecked - uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +** App_Callback - void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** Notify_Callback - void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** ApplicationStarted - bool CDC1_ApplicationStarted(void); +** TransactionsStarted - bool CDC1_TransactionsStarted(void); +** App_Task - uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +** StdIOKeyPressed - bool CDC1_StdIOKeyPressed(void); +** StdIOReadChar - void CDC1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void CDC1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr CDC1_GetStdio(void); +** Deinit - uint8_t CDC1_Deinit(void); +** Init - uint8_t CDC1_Init(void); +** +** * Copyright : USB Stack sources (c) Copyright Freescale, all rights reserved, 2013-2017 +** * Adapted for Processor Expert: Erich Styger, 2015-2019 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** ###################################################################*/ +/*! +** @file CDC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CDC1_module CDC1 module documentation +** @{ +*/ + +/* MODULE CDC1. */ + +#include "CDC1.h" +#include "hidef.h" /* for EnableInterrupts macro */ +#include "derivative.h" /* include peripheral declarations */ +#include "types.h" /* Contains User Defined Data Types */ +#include "usb_cdc.h" /* USB CDC Class Header File */ +#include +/* skip the inclusion in dependency state */ +#ifndef __NO_SETJMP + #include +#endif +#include +#include +#if CDC1_CONFIG_USE_TIMEOUT + #include "TMOUT1.h" +#endif +#include "WAIT1.h" + +#define CONTROLLER_ID (0) /* ID to identify USB CONTROLLER */ + +#if HIGH_SPEED_DEVICE +static uint_32 g_cdcBuffer[DIC_BULK_OUT_ENDP_PACKET_SIZE>>1]; +#endif + +/* Virtual COM Application start Init Flag */ +static volatile boolean start_app = FALSE; + +/* Virtual COM Application Carrier Activate Flag */ +static volatile boolean start_transactions = FALSE; +static volatile boolean transactionOngoing = FALSE; + +/* default standard I/O struct */ +CLS1_ConstStdIOType CDC1_stdio = { + (CLS1_StdIO_In_FctType)CDC1_StdIOReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)CDC1_StdIOSendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)CDC1_StdIOSendChar, /* stderr */ + CDC1_StdIOKeyPressed /* if input is not empty */ + }; +uint8_t CDC1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +/* +** =================================================================== +** Method : GetFreeInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of free character in the send buffer +** Parameters : None +** Returns : +** --- - Number of free character in the receive +** buffer. +** =================================================================== +*/ +/* +uint16_t CDC1_GetFreeInTxBuf(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : GetCharsInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the send buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ +/* +uint16_t CDC1_GetCharsInTxBuf(void) +{ + *** implemented as macro in the header file + return (uint16_t)Tx1_NofElements(); +} +*/ + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the receive buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ +uint16_t CDC1_GetCharsInRxBuf(void) +{ + static uint8_t txBuf[CDC1_DATA_BUFF_SIZE]; + + if (CDC1_App_Task(txBuf, sizeof(txBuf))!=ERR_OK) { /* call USB handler: if active, then this will empty the buffer */ + } + return (uint16_t)Rx1_NofElements(); +} + +/* +** =================================================================== +** Method : GetChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is not +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ +/** +uint8_t CDC1_GetChar(CDC1_TComData *Chr) +{ + *** implemented as macro in the header file + return Rx1_Get(Chr); +} +*/ +/* +** =================================================================== +** Method : RecvChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ +uint8_t CDC1_RecvChar(CDC1_TComData *Chr) +{ + while(Rx1_Get(Chr)!=ERR_OK) { + WAIT1_WaitOSms(10); /* avoid to completely block */ + /* retry receiving until success */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendChar (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a character to the USB interface. Method is +** non-blocking: If the output buffer is full, it tries to send +** it over USB. If this fails or buffer is still full, the +** character will be lost. If OnError() event is enabled, the +** error event will be called in case of error. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendChar(CDC1_TComData Chr) +{ + static uint8_t txBuf[CDC1_DATA_BUFF_SIZE]; + uint8_t res; + + if (Tx1_Put(Chr)==ERR_TXFULL) { /* retry once, otherwise throw it away */ + res = CDC1_App_Task(txBuf, sizeof(txBuf)); /* call USB handler: if active, then this will empty the buffer */ + if (res==ERR_BUSOFF) { /* USB not enumerated */ + return ERR_FAILED; + } else if (res!=ERR_OK) { + return ERR_TXFULL; + } else { /* retry, as USB App_Task() should have sent the buffer */ + return Tx1_Put(Chr); /* retry. If buffer is still full, we will lose the character */ + } + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendBlock (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a data block to the USB interface. Method is +** non-blocking: if data cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to send. +** dataSize - Size of data in bytes +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize) +{ + uint8_t res = ERR_OK; + + while(dataSize > 0) { + if (CDC1_SendChar(*data)!=ERR_OK) { + res = ERR_TXFULL; + } + dataSize--; data++; + } + return res; +} + +/* +** =================================================================== +** Method : SendString (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a string to the USB interface. Method is +** non-blocking: if string cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to string to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendString(CDC1_TComData *Chr) +{ + uint8_t res = ERR_OK; + + while(*Chr != '\0') { + if (CDC1_SendChar(*Chr)!=ERR_OK) { + res = ERR_TXFULL; + } + Chr++; + } + return res; +} + +/* +** =================================================================== +** Method : App_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle class callbacks from USB +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - gives the configuration value +** Returns : Nothing +** =================================================================== +*/ +void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val) +{ + UNUSED(controller_ID); + UNUSED(val); + if (event_type == USB_APP_BUS_RESET) { + start_app = FALSE; + } else if (event_type == USB_APP_ENUM_COMPLETE) { +#if HIGH_SPEED_DEVICE + /* prepare for the next receive event */ + USB_Class_CDC_Interface_DIC_Recv_Data(&controller_ID, + (uint_8_ptr)g_cdcBuffer, + DIC_BULK_OUT_ENDP_PACKET_SIZE); +#else + (void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); +#endif + start_app = TRUE; + } else if ((event_type==USB_APP_DATA_RECEIVED) && (start_transactions==TRUE)) { + /* Copy Received Data buffer to Application Buffer */ + USB_PACKET_SIZE BytesToBeCopied; + APP_DATA_STRUCT *dp_rcv = (APP_DATA_STRUCT*)val; + uint_8 idx; + + BytesToBeCopied = (USB_PACKET_SIZE)((dp_rcv->data_size>CDC1_DATA_BUFF_SIZE) ? CDC1_DATA_BUFF_SIZE:dp_rcv->data_size); + for(idx = 0; idxdata_ptr[idx])!=ERR_OK) { + /* Failed to put byte into buffer. Is the buffer to small? Then increase the Rx buffer. + Otherwise not much we could do here, so we are loosing byte here. + */ + /* Enable OnError() event so this event will be called here */ + } + } + (void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); /* see http://eprints.utar.edu.my/143/1/BI-2011-0708672-1.pdf, page 131 */ + } else if ((event_type==USB_APP_SEND_COMPLETE) && (start_transactions==TRUE)) { + transactionOngoing = FALSE; + /* Previous Send is complete. Queue next receive */ +#if HIGH_SPEED_DEVICE + //(void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, g_cdcBuffer, 0); +#else + //(void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); +#endif + } else if (event_type == USB_APP_ERROR) { /* detach? */ + start_app = FALSE; + start_transactions = FALSE; + } else if (event_type == USB_APP_BUS_SUSPEND) { /* disconnected cable? */ + start_app = FALSE; + start_transactions = FALSE; + } +} + +/* +** =================================================================== +** Method : Notify_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle PSTN Sub Class callbacks +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - +** Returns : Nothing +** =================================================================== +*/ +void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val) +{ + UNUSED(controller_ID); + UNUSED(val); + if (start_app == TRUE) { + if(event_type == USB_APP_CDC_CARRIER_ACTIVATED) { + start_transactions = TRUE; + } else if(event_type == USB_APP_CDC_CARRIER_DEACTIVATED) { + start_transactions = FALSE; + } + } +#if 1 /* not needed any more? see https://community.freescale.com/message/605537?et=watches.email.thread# */ + start_transactions = TRUE; /* ??? see http://forums.freescale.com/t5/Freescale-MQX-trade-USB-Host/Cant-get-CDC-virtual-com-demo-to-work-with-VB2005-on-xp-sp3/m-p/92713#M302 */ +#endif +} + +/* +** =================================================================== +** Method : CDC1_RunUsbEngine (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void CDC1_RunUsbEngine(void) +{ + /* not needed */ +} + +/* +** =================================================================== +** Method : CDC1_SendDataBlock (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +uint8_t CDC1_SendDataBlock(uint8_t *data, size_t dataSize) +{ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + TMOUT1_CounterHandle timeout; +#endif + uint8_t res = ERR_OK; + + transactionOngoing = TRUE; + if (USB_Class_CDC_Interface_DIC_Send_Data(CONTROLLER_ID, data, dataSize)!=USB_OK) { + transactionOngoing = FALSE; + return ERR_FAULT; + } + /* wait for transaction finish */ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + timeout = TMOUT1_GetCounter(CDC1_CONFIG_APP_TASK_TIMEOUT_MS/TMOUT1_TICK_PERIOD_MS); /* set up timeout counter */ +#endif + while(transactionOngoing) { /* wait until transaction is finished */ + /*lint -save -e522 function lacks side-effects */ + CDC1_RunUsbEngine(); + /*lint -restore */ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + if (TMOUT1_CounterExpired(timeout)) { + res = ERR_FAILED; + break; + } +#endif + WAIT1_WaitOSms(10); /* wait some time */ + } +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + TMOUT1_LeaveCounter(timeout); /* return timeout counter */ +#endif + return res; +} + +/* +** =================================================================== +** Method : App_Task (component FSL_USB_CDC_Device) +** +** Description : +** Application task to be called periodically from the main +** task. +** Parameters : +** NAME - DESCRIPTION +** * txBuf - Pointer to temporary buffer used to +** transmit data over USB. Should be equal or +** greater than the endpoint buffer size. Data +** will be sent in an asynchronous way, so +** make sure the buffer is *not* on the stack. +** This buffer must be available until the +** next transmission. +** txBufSize - Size of the buffer in bytes +** Returns : +** --- - Error code, returns ERR_OK if USB +** enumeration has been finished, error code +** otherwise. +** =================================================================== +*/ +uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize) +{ + size_t i; + uint8_t res; + + /* device is Kinetis K20D50 */ + /*lint -save -e522 function lacks side-effects */ + CDC1_RunUsbEngine(); + /*lint -restore */ + /* call the periodic task function */ + USB_Class_CDC_Periodic_Task(); + /* check whether enumeration is complete or not */ + if ((start_app==TRUE) && (start_transactions==TRUE)) { + if (Tx1_NofElements()!=0) { + i = 0; + while(iCDC1_GetFreeInTxBuf()) { /* no room at the Inn... */ + res = ERR_TXFULL; + } else { + res = ERR_OK; + while(bufSize>0 && res==ERR_OK) { + res = Tx1_Put(*buf); + bufSize--; + buf++; + } + } + return res; +} + +/* +** =================================================================== +** Method : ClearRxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the receiver buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void CDC1_ClearRxBuffer(void) +{ + Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ClearTxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the transmit buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void CDC1_ClearTxBuffer(void) +{ + Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : StdIOKeyPressed (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in the +** input/RX buffer +** =================================================================== +*/ +bool CDC1_StdIOKeyPressed(void) +{ + return (bool)((CDC1_GetCharsInRxBuf()==0U) ? FALSE : TRUE); /* true if there are characters in receive buffer */ +} + +/* +** =================================================================== +** Method : StdIOReadChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ +void CDC1_StdIOReadChar(uint8_t *c) +{ + if (CDC1_RecvChar((uint8_t *)c) != ERR_OK) { + /* failed to receive character: return a zero character */ + *c = '\0'; + } +} + +/* +** =================================================================== +** Method : StdIOSendChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send. +** Returns : Nothing +** =================================================================== +*/ +void CDC1_StdIOSendChar(uint8_t ch) +{ + while (CDC1_SendChar((uint8_t)ch)==ERR_TXFULL){} /* Send char */ +} + +/* +** =================================================================== +** Method : ApplicationStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if the CDC application has been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CDC1_ApplicationStarted(void) +{ + return start_app; /* TRUE if CDC is running */ +} + +/* +** =================================================================== +** Method : TransactionsStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if USB transactions have been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CDC1_TransactionsStarted(void) +{ + return start_transactions; /* port open on host */ +} + +/* +** =================================================================== +** Method : GetStdio (component FSL_USB_CDC_Device) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr CDC1_GetStdio(void) +{ + return &CDC1_stdio; +} + +/* END CDC1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.h new file mode 100644 index 0000000..8690c4f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1.h @@ -0,0 +1,502 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CDC1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FSL_USB_CDC_Device +** Version : Component 01.103, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : CDC1 +** Shell : CLS1 +** CPU : Kinetis K20D50 +** CDC Settings : Enabled +** .inf ClassGuid : 4D36E978-E325-11CE-BFC1-08002BE10318 +** .inf VID : 0x2504 +** .inf PID : 0x0300 +** .inf PRVDR : Freescale +** .inf MFGNAME : My Company +** .inf DESCRIPTION : Freescale CDC Device +** .inf SERVICE : Virtual Com Driver +** Bus reported device : FSL CDC DEVICE +** Bus reported vendor : FREESCALE INC. +** Serial Number : 000123ABC +** Device Subclass : 0 +** Configuration : +** USB_EP0_SIZE (in) : 32 +** USB_EP1_SIZE (out) : 32 +** USB_EP2_SIZE (notify) : 32 +** Send Buffer : RingBuffer +** Receive Buffer : RingBuffer +** SendDataBlock : +** Use Timeout : Enabled +** Timeout : TMOUT1 +** App Task Timeout (ms) : 20 +** Waiting time (ms) : 10 +** Wait : WAIT1 +** Power Options : +** Bus Powered : yes +** Self Powered : yes +** Current Draw (mA) : 100 +** Contents : +** ClearRxBuffer - void CDC1_ClearRxBuffer(void); +** ClearTxBuffer - void CDC1_ClearTxBuffer(void); +** GetFreeInTxBuf - uint16_t CDC1_GetFreeInTxBuf(void); +** GetCharsInTxBuf - uint16_t CDC1_GetCharsInTxBuf(void); +** GetCharsInRxBuf - uint16_t CDC1_GetCharsInRxBuf(void); +** GetChar - uint8_t CDC1_GetChar(CDC1_TComData *Chr); +** RecvChar - uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +** SendChar - uint8_t CDC1_SendChar(CDC1_TComData Chr); +** SendString - uint8_t CDC1_SendString(CDC1_TComData *Chr); +** SendBlock - uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +** PutBufferChecked - uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +** App_Callback - void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** Notify_Callback - void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** ApplicationStarted - bool CDC1_ApplicationStarted(void); +** TransactionsStarted - bool CDC1_TransactionsStarted(void); +** App_Task - uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +** StdIOKeyPressed - bool CDC1_StdIOKeyPressed(void); +** StdIOReadChar - void CDC1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void CDC1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr CDC1_GetStdio(void); +** Deinit - uint8_t CDC1_Deinit(void); +** Init - uint8_t CDC1_Init(void); +** +** * Copyright : USB Stack sources (c) Copyright Freescale, all rights reserved, 2013-2017 +** * Adapted for Processor Expert: Erich Styger, 2015-2019 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** ###################################################################*/ +/*! +** @file CDC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CDC1_module CDC1 module documentation +** @{ +*/ + +#ifndef __CDC1_H +#define __CDC1_H + +/* MODULE CDC1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CDC1config.h" /* configuration */ + +#include /* for size_t */ +#include "CLS1.h" /* shell interface */ +#include "Rx1.h" +#include "Tx1.h" + + +#ifndef __BWUserType_CDC1_TComData +#define __BWUserType_CDC1_TComData + typedef uint8_t CDC1_TComData ; /* User type for communication data type. */ +#endif + +/* + DATA_BUFF_SIZE should be greater than or equal to the endpoint buffer size, + otherwise there will be data loss. For MC9S08JS16, maximum DATA_BUFF_SIZE + supported is 16 Bytes +*/ +#define CDC1_DATA_BUFF_SIZE CDC1_CONFIG_DATA_BUF_SIZE + +#define CDC1_USB_ERR_SEND 1 /* Error while sending */ +#define CDC1_USB_ERR_BUSOFF 2 /* Bus not ready */ +#define CDC1_USB_ERR_INIT 3 /* USB initialization error */ +#define CDC1_USB_ERR_TX_CHAR 4 /* Error sending character */ +#define CDC1_USB_ERR_TX_STRING 5 /* Error sending string */ +#define CDC1_USB_ERR_CHECKED_TXFULL 6 /* Error during sending a checked block */ +#define CDC1_USB_ERR_RECEIVE 7 /* Error while starting an receive transaction */ +#define CDC1_USB_ERR_RX_PUT 8 /* Error while putting RX byte into buffer */ +#define CDC1_USB_ERR_TX_BLOCK 9 /* Error sending data block */ +#define CDC1_USB_TIMEOUT_SEND 10 /* Timeout while sending */ +#define CDC1_USB_ERR_DEINIT 11 /* USB deinitialization error */ + +extern CLS1_ConstStdIOType CDC1_stdio; /* default standard I/O */ +extern uint8_t CDC1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +#define CDC1_GetFreeInTxBuf() \ + Tx1_NofFreeElements() +/* +** =================================================================== +** Method : GetFreeInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of free character in the send buffer +** Parameters : None +** Returns : +** --- - Number of free character in the receive +** buffer. +** =================================================================== +*/ + +uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +/* +** =================================================================== +** Method : RecvChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ + +uint8_t CDC1_SendChar(CDC1_TComData Chr); +/* +** =================================================================== +** Method : SendChar (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a character to the USB interface. Method is +** non-blocking: If the output buffer is full, it tries to send +** it over USB. If this fails or buffer is still full, the +** character will be lost. If OnError() event is enabled, the +** error event will be called in case of error. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +#define CDC1_GetCharsInTxBuf() \ + Tx1_NofElements() +/* +** =================================================================== +** Method : GetCharsInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the send buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ + +uint16_t CDC1_GetCharsInRxBuf(void); +/* +** =================================================================== +** Method : GetCharsInRxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the receive buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ + +uint8_t CDC1_Init(void); +/* +** =================================================================== +** Method : Init (component FSL_USB_CDC_Device) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +/* +** =================================================================== +** Method : App_Task (component FSL_USB_CDC_Device) +** +** Description : +** Application task to be called periodically from the main +** task. +** Parameters : +** NAME - DESCRIPTION +** * txBuf - Pointer to temporary buffer used to +** transmit data over USB. Should be equal or +** greater than the endpoint buffer size. Data +** will be sent in an asynchronous way, so +** make sure the buffer is *not* on the stack. +** This buffer must be available until the +** next transmission. +** txBufSize - Size of the buffer in bytes +** Returns : +** --- - Error code, returns ERR_OK if USB +** enumeration has been finished, error code +** otherwise. +** =================================================================== +*/ + +uint8_t CDC1_SendString(CDC1_TComData *Chr); +/* +** =================================================================== +** Method : SendString (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a string to the USB interface. Method is +** non-blocking: if string cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to string to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +#define CDC1_GetChar(Chr) \ + Rx1_Get(Chr) + +/* +** =================================================================== +** Method : GetChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is not +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ + +uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : PutBufferChecked (component FSL_USB_CDC_Device) +** +** Description : +** Puts a data block into the output buffer, but does not send +** it. If there is not enough size available, then ERR_TXFULL +** is returned, otherwise ERR_OK. The application then needs to +** call USB_App_Callback() to actually send the buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be sent +** bufsize - Buffer size in bytes +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +/* +** =================================================================== +** Method : App_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle class callbacks from USB +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - gives the configuration value +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +/* +** =================================================================== +** Method : Notify_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle PSTN Sub Class callbacks +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - +** Returns : Nothing +** =================================================================== +*/ + +#define CDC1_ClearRxBuffer() \ + Rx1_Clear() +/* +** =================================================================== +** Method : ClearRxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the receiver buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define CDC1_ClearTxBuffer() \ + Tx1_Clear() +/* +** =================================================================== +** Method : ClearTxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the transmit buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_RunUsbEngine(void); +/* +** =================================================================== +** Method : CDC1_RunUsbEngine (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +/* +** =================================================================== +** Method : SendBlock (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a data block to the USB interface. Method is +** non-blocking: if data cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to send. +** dataSize - Size of data in bytes +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +uint8_t CDC1_SendDataBlock(uint8_t *data, size_t dataSize); +/* +** =================================================================== +** Method : CDC1_SendDataBlock (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t CDC1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FSL_USB_CDC_Device) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool CDC1_StdIOKeyPressed(void); +/* +** =================================================================== +** Method : StdIOKeyPressed (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in the +** input/RX buffer +** =================================================================== +*/ + +void CDC1_StdIOReadChar(uint8_t *c); +/* +** =================================================================== +** Method : StdIOReadChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_StdIOSendChar(uint8_t ch); +/* +** =================================================================== +** Method : StdIOSendChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send. +** Returns : Nothing +** =================================================================== +*/ + +bool CDC1_ApplicationStarted(void); +/* +** =================================================================== +** Method : ApplicationStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if the CDC application has been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool CDC1_TransactionsStarted(void); +/* +** =================================================================== +** Method : TransactionsStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if USB transactions have been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr CDC1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component FSL_USB_CDC_Device) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END CDC1. */ + +#endif +/* ifndef __CDC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1config.h new file mode 100644 index 0000000..4979fce --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CDC1config.h @@ -0,0 +1,20 @@ +#ifndef __CDC1_CONFIG_H +#define __CDC1_CONFIG_H + +#ifndef CDC1_CONFIG_USE_TIMEOUT + #define CDC1_CONFIG_USE_TIMEOUT 1 + /*!< 1: Use timeout; 0: do not use timeout */ +#endif + +#ifndef CDC1_CONFIG_APP_TASK_TIMEOUT_MS + #define CDC1_CONFIG_APP_TASK_TIMEOUT_MS 20 + /*!< App Task timeout in milliseconds, 0 to disable timout */ +#endif + +#ifndef CDC1_CONFIG_DATA_BUF_SIZE + #define CDC1_CONFIG_DATA_BUF_SIZE (64) + /*!< Value used for CDC1_DATA_BUF_SIZE, must be a multiple of endpoint size. The greater the value, the better the performance */ +#endif + + +#endif /* __CDC1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.c new file mode 100644 index 0000000..469f02f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.c @@ -0,0 +1,1487 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:40, # CodeGen: 32 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD> " +** Project Name : SolderPaste Dispenser +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Disabled +** Utility : UTIL1 +** Default Serial : Enabled +** Console Interface : RTT1 +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + +/* MODULE CLS1. */ +#include /* for isalnum*/ + +#include "CLS1.h" +#include "XF1.h" +#include "UTIL1.h" +#include "CS1.h" + #include "WAIT1.h" + +#if CLS1_DEFAULT_SERIAL + #include CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE +#endif + + +uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +#if CLS1_HISTORY_ENABLED + static uint8_t CLS1_history[CLS1_NOF_HISTORY][CLS1_HIST_LEN]; /* History buffers */ + static uint8_t CLS1_history_index = 0; /* Selected command */ +#endif +#if CLS1_ECHO_ENABLED + static bool CLS1_EchoEnabled = TRUE; +#endif + +#if CLS1_CONFIG_USE_MUTEX + #include "FreeRTOS.h" + #include "task.h" + #include "semphr.h" +#endif + +#ifdef __HC08__ + #pragma MESSAGE DISABLE C3303 /* implicit concatenation of strings */ +#endif +#if CLS1_CONFIG_USE_MUTEX + static SemaphoreHandle_t ShellSem = NULL; /* Semaphore to protect shell SCI access */ +#endif + +#if CLS1_DEFAULT_SERIAL + CLS1_ConstStdIOType CLS1_stdio = + { + (CLS1_StdIO_In_FctType)CLS1_ReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stderr */ + CLS1_KeyPressed /* if input is not empty */ + }; + static CLS1_ConstStdIOType *CLS1_currStdIO = &CLS1_stdio; +#else + static CLS1_ConstStdIOType *CLS1_currStdIO = NULL; /* needs to be set through CLS1_SetStdio(); */ +#endif +/* Internal method prototypes */ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io); + +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + io(ch); +} + +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +/*! + * \brief Prints a string using I/O callbacks + * \param[in] str String (zero terminated) to be printed + * \param[in] io I/O function to be used for printing + */ +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + while(*str!='\0') { + io(*str++); + } +} + +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-1234567890")]; + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("1234567890")]; + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-12345")]; + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("12345")]; + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("123")]; + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-123")]; + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io) +{ + if (UTIL1_strcmp((char*)cmd, CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, "CLS1 help")==0) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROJECT_NAME_STRING, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)"CLS1", (const unsigned char*)"Group of CLS1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (const unsigned char*)"Print help or status information\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendHelpStr((unsigned char*)" echo (on|off)", (const unsigned char*)"Turn echo on or off\r\n", io->stdOut); +#endif + *handled = TRUE; + return ERR_OK; +#if CLS1_ECHO_ENABLED + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo on")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = TRUE; + return ERR_OK; + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo off")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = FALSE; + return ERR_OK; +#endif + } else if ((UTIL1_strcmp((char*)cmd, CLS1_CMD_STATUS)==0) || (UTIL1_strcmp((char*)cmd, "CLS1 status")==0)) { + *handled = TRUE; + return CLS1_PrintStatus(io); + } + return ERR_OK; /* no error */ +} + +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); /* ensure that there is a new line */ + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROMPT_STRING, io->stdOut); +} + +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev) +{ + *isPrev = FALSE; +#if CLS1_HISTORY_ENABLED + if ( cmdBufIdx==0 /* first character on command line */ + || (UTIL1_strcmp((const char*)cmdBuf, (const char*)CLS1_history[CLS1_history_index])==0) /* pressing prev/next character on previous history element */ + ) + { + if (ch==CLS1_HISTORY_PREV_CHAR) { + *isPrev = TRUE; + return TRUE; + } else if (ch==CLS1_HISTORY_NEXT_CHAR) { + *isPrev = FALSE; + return TRUE; + } + } +#if 0 + if (cmdBufIdx==0 || cmdBufIdx==2) { /* accept only first character or sequence as history sequence */ + if (cmdBufIdx==2 && cmdBuf[0]==0x1b && cmdBuf[1]==0x5b) { + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (cmdBuf[2]==0x41 /* up */ || cmdBuf[2]==0x44 /* left */) { + *isPrev = TRUE; + return TRUE; + } else if (cmdBuf[2]==0x42 /* down */ || cmdBuf[2]==0x43 /* right */) { + *isPrev = FALSE; + return TRUE; + } + } + /* \todo: handle TAB and SHIFT-TAB */ + } +#endif +#else + (void)ch; /* not used */ + (void)cmdBuf; /* not used */ + (void)cmdBufIdx; /* not used */ +#endif + return FALSE; +} + +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io) +{ + uint8_t c; + bool isBackwardHistory; + + if (io->keyPressed()) { + for(;;) { /* while not '\r' or '\n' */ + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + if (c=='\0') { /* nothing in rx buffer? Something is wrong... */ + break; /* get out of loop */ + } + if (c=='\b' || c=='\177') { /* check for backspace */ + if (buf > bufStart) { /* Avoid buffer underflow */ +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut('\b'); /* delete character on terminal */ + io->stdOut(' '); + io->stdOut('\b'); + } +#endif + buf--; /* delete last character in buffer */ + *buf = '\0'; + bufSize++; + } + } else if (CLS1_IsHistoryCharacter(c, bufStart, (size_t)(buf-bufStart), &isBackwardHistory)) { +#if CLS1_HISTORY_ENABLED + uint8_t cBuf[3]={'\0','\0','\0'}, cBufIdx = 0; + bool prevInHistory; +#endif + + while (c!='\0') { /* empty the rx buffer (escape sequence) */ +#if CLS1_HISTORY_ENABLED + cBuf[cBufIdx] = c; + cBufIdx++; + if (cBufIdx==sizeof(cBuf)) { + cBufIdx = 0; /* ring buffer */ + } +#endif + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + } +#if CLS1_HISTORY_ENABLED + /* if not an alphanumeric switch to history */ + prevInHistory = cBufIdx==0 && cBuf[0]==0x1b && cBuf[1]==0x5b && (cBuf[2]==0x41 /*up*/ || cBuf[2]==0x44 /*left*/); + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (prevInHistory) { + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + CLS1_history_index++; /* update the index */ + if (CLS1_history_index==CLS1_NOF_HISTORY) { + CLS1_history_index = 0; + } + } else { + if (CLS1_history_index==0) { + CLS1_history_index = (CLS1_NOF_HISTORY-1); + } else { + CLS1_history_index--; + } + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + } + bufSize = bufSize + buf - bufStart - UTIL1_strlen((const char*)bufStart); /* update the buffer */ + buf = bufStart + UTIL1_strlen((const char*)bufStart); +#endif +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_PrintPrompt(io); + CLS1_SendStr(bufStart, io->stdOut); + } +#endif + } else { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut(c); /* echo character */ + } +#endif + *buf = (uint8_t)c; /* append character to the string */ + buf++; + bufSize--; + if ((c=='\r') || (c=='\n')) { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\n", io->stdOut); + } +#endif +#if CLS1_HISTORY_ENABLED + if ((bufStart[0] != '\0') && (bufStart[0] != '\r') && (bufStart[0] != '\n')) { + int i; + + for(i=CLS1_NOF_HISTORY-1; i>0;i--) { + UTIL1_strcpy(CLS1_history[i], CLS1_HIST_LEN, CLS1_history[i-1]); /* move previous commands */ + } + CLS1_history_index = 0; /* update the history with the current command */ + UTIL1_strcpy(CLS1_history[0], CLS1_HIST_LEN, bufStart); /* add the current command to the history */ + if (buf-bufStart <= CLS1_HIST_LEN) { /* size check */ + CLS1_history[0][buf-bufStart-1] = '\0'; + } else { + CLS1_history[0][CLS1_HIST_LEN-1] = '\0'; + } + } +#endif + break; + } + if (bufSize <= 1) { /* buffer full */ + break; + } + } + } /* for */ + *buf = '\0'; /* zero terminate string */ + return TRUE; + } else { + return FALSE; + } +} + +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io) +{ + CLS1_SendStatusStr((const unsigned char*)"CLS1", (const unsigned char*)"\r\n", io->stdOut); + CLS1_SendStatusStr((const unsigned char*)" Build", (const unsigned char*)__DATE__, io->stdOut); + CLS1_SendStr((unsigned char*)" ", io->stdOut); + CLS1_SendStr((unsigned char*)__TIME__, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendStatusStr((const unsigned char*)" echo", CLS1_EchoEnabled?(const unsigned char*)"On\r\n":(const unsigned char*)"Off\r\n", io->stdOut); +#endif + return ERR_OK; +} + +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"*** Failed or unknown command: ", io->stdErr); + CLS1_SendStr(cmd, io->stdErr); + CLS1_SendStr((unsigned char*)"\r\n", io->stdErr); + CLS1_SendStr((unsigned char*)"*** Type ", io->stdErr); + CLS1_SendStr((unsigned char*)CLS1_CMD_HELP, io->stdErr); + CLS1_SendStr((unsigned char*)" to get a list of available commands\r\n", io->stdErr); +} + +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable) +{ + uint8_t res = ERR_OK; + + if (parserTable==NULL) { /* no table??? */ + return ERR_FAILED; + } + if (io==NULL) { /* no IO handler??? */ + return ERR_FAILED; + } + /* iterate through all parser functions in table */ + while(*parserTable!=NULL) { + if ((*parserTable)(cmd, handled, io)!=ERR_OK) { + res = ERR_FAILED; + } + parserTable++; + } + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + uint8_t res = ERR_OK; + bool handled; +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + bool silentPrefix = FALSE; +#endif +#if CLS1_CONFIG_MULTI_CMD_ENABLED + uint8_t buf[CLS1_CONFIG_MULTI_CMD_SIZE]; + uint8_t i; + bool parseBuffer, finished; +#endif + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + if (*cmd=='\0') { /* empty command */ + return ERR_OK; + } +#if CLS1_CONFIG_MULTI_CMD_ENABLED + parseBuffer = FALSE; + finished = FALSE; + i = 0; + for(;;) { /* breaks */ + if (i>sizeof(buf)-2) { + res = ERR_FAILED; + CLS1_PrintCommandFailed(buf, io); + break; /* buffer overflow */ + } + buf[i] = *cmd; + cmd++; i++; + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (i==1 && buf[0]==CLS1_SILENT_PREFIX_CHAR) { /* first character is silent character */ + silentPrefix |= (bool)(buf[0]==CLS1_SILENT_PREFIX_CHAR); + buf[0] = *cmd; /* skip silent character */ + cmd++; + } + #endif + if (buf[i-1] == CLS1_CONFIG_MULTI_CMD_CHAR) { /* found separator */ + buf[i-1] = '\0'; + parseBuffer = TRUE; + } else if (buf[i-1]=='\0') { + parseBuffer = TRUE; + finished = TRUE; + } + if (parseBuffer) { + handled = FALSE; + res = CLS1_IterateTable(buf, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command, or error? */ + CLS1_PrintCommandFailed(buf, io); + res = ERR_FAILED; + } + parseBuffer = FALSE; + i = 0; /* restart */ + } + if (finished) { + break; /* get out of loop */ + } + } /* for */ +#else + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + silentPrefix = (bool)(*cmd==CLS1_SILENT_PREFIX_CHAR); + if (silentPrefix) { + cmd++; /* skip silent character */ + } + #endif + handled = FALSE; + res = CLS1_IterateTable(cmd, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command? */ + CLS1_PrintCommandFailed(cmd, io); + res = ERR_FAILED; + } +#endif +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (!silentPrefix && !silent) { + CLS1_PrintPrompt(io); + } +#else + if (!silent) { + CLS1_PrintPrompt(io); + } +#endif + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ParseWithCommandTableExt(cmd, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio) +{ + CLS1_currStdIO = stdio; + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void) +{ + return CLS1_currStdIO; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + /* IMPORTANT NOTE: this function *appends* to the buffer, so the buffer needs to be initialized first! */ + uint8_t res = ERR_OK; + size_t len; + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + len = UTIL1_strlen((const char*)cmdBuf); + if (CLS1_ReadLine(cmdBuf, cmdBuf+len, cmdBufSize-len, io)) { + len = UTIL1_strlen((const char*)cmdBuf); /* length of buffer string */ + if (len==0) { /* error case */ + return ERR_FAILED; + } else if (len==1 && (cmdBuf[0]=='\n' || cmdBuf[0]=='\r')) { /* eat preceding newline characters */ + cmdBuf[0] = '\0'; + } + if (len>=cmdBufSize-1) { /* buffer overflow? Parse what we have, will be likely return an error */ + (void)CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + res = ERR_OVERFLOW; + } else if (cmdBuf[len-1]=='\n' || cmdBuf[len-1]=='\r') { /* line end: parse command */ + cmdBuf[len-1] = '\0'; /* remove line end character for parser */ + res = CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + } else { + /* continue to append to buffer */ + } + } + return res; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ReadAndParseWithCommandTableExt(cmdBuf, cmdBufSize, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_RequestSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +} + +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReleaseSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ +void* CLS1_GetSemaphore(void) +{ +#if CLS1_CONFIG_USE_MUTEX + return ShellSem; +#else + return NULL; +#endif +} + +/* +** =================================================================== +** Method : SendSeparatedStrings (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io) +{ + /* write command part */ + if (strA!=NULL) { + while(*strA!='\0' && tabPos>0) { + io(*strA++); + tabPos--; + } + } + /* fill up until ';' */ + while(tabPos>0) { + io(' '); + tabPos--; + } + /* write separator */ + io(tabChar); + io(' '); + if (strB!=NULL) { + /* write help text */ + CLS1_SendStr(strB, io); + } +} + +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io) +{ + #define HELP_SEMICOLON_POS 26 /* position of the ';' after the command string */ + SendSeparatedStrings(strCmd, strHelp, ';', HELP_SEMICOLON_POS, io); +} + +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io) +{ + #define STATUS_COLON_POS 13 /* position of the ':' after the item string */ + SendSeparatedStrings(strItem, strStatus, ':', STATUS_COLON_POS, io); +} + +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReadChar(uint8_t *c) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + uint8_t res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif + res = CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME((uint8_t*)c); + if (res==ERR_RXEMPTY) { + /* no character in buffer */ + *c = '\0'; + } +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +#else + *c = '\0'; + return; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendChar(uint8_t ch) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + CLS1_SendCharFct(ch, CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME); +#else + (void)ch; /* avoid compiler warning about unused argument */ +#endif +} + +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CLS1_KeyPressed(void) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + bool res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_DEFAULT_SERIAL + res = (bool)((CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME()==0U) ? FALSE : TRUE); /* true if there are characters in receive buffer */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif + return res; +#else + return FALSE; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_Init(void) +{ +#if CLS1_CONFIG_USE_MUTEX +#if configSUPPORT_STATIC_ALLOCATION + static StaticSemaphore_t xMutexBuffer; +#endif + bool schedulerStarted; + CS1_CriticalVariable(); + + schedulerStarted = (bool)(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED); + if (!schedulerStarted) { /* FreeRTOS not started yet. We are called in PE_low_level_init(), and interrupts are disabled */ + CS1_EnterCritical(); + } +#if configSUPPORT_STATIC_ALLOCATION + ShellSem = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer); +#else + ShellSem = xSemaphoreCreateRecursiveMutex(); +#endif + if (!schedulerStarted) { /* above RTOS call might have enabled interrupts! Make sure we restore the state */ + CS1_ExitCritical(); + } + if (ShellSem==NULL) { /* semaphore creation failed */ + for(;;) {} /* error, not enough memory? */ + } + vQueueAddToRegistry(ShellSem, "CLS1_Sem"); +#endif +#if CLS1_HISTORY_ENABLED + { + int i; + + CLS1_history_index = 0; + for(i=0; i0) { + io(*data++); + dataSize--; + } +} + +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void CLS1_printfPutChar(void *arg, char c) +{ + CLS1_StdIO_OutErr_FctType fct = (CLS1_StdIO_OutErr_FctType)arg; + + fct(c); /* print character */ +} + +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)io->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printf(const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)CLS1_GetStdio()->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)) +{ +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + uint8_t res; + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + int timeoutMs = CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif +#endif + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + do { + res = fct((uint8_t)ch); /* Send char, returns error code */ + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if (res==ERR_TXFULL) { + #if CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + WAIT1_WaitOSms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #else + WAIT1_Waitms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #endif + } + #endif + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS; + #endif + } while(res==ERR_TXFULL); +#else + (void)fct((uint8_t)ch); /* non blocking send */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io) +{ + #define NOF_BYTES_PER_LINE 32 /* how many bytes are shown on a line. This defines as well the chunk size we read from memory */ + #define MAX_NOF_BYTES_PER_LINE 32 + uint8_t buf[MAX_NOF_BYTES_PER_LINE]; /* this is the chunk of data we get (per line in output) */ + uint8_t str[3*MAX_NOF_BYTES_PER_LINE+((MAX_NOF_BYTES_PER_LINE+1)/8)+1]; /* maximum string for output: + - '3*' because each byte is 2 hex digits plus a space + - '(NOF_BYTES_PER_LINE+1)/8' because we add a space between every 8 byte block + - '+1' for the final zero byte */ + uint32_t addr; + uint8_t res=0, j, bufSize; + uint8_t ch; + + if (endAddrstdErr); + return ERR_RANGE; + } + for(addr=startAddr; addr<=endAddr; /* nothing */ ) { + if (endAddr-addr+1 >= bytesPerLine) { /* read only part of buffer */ + bufSize = bytesPerLine; /* read full buffer */ + } else { + bufSize = (uint8_t)(endAddr-addr+1); + } + if (readfp(hndl, addr, buf, bufSize)!=ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Read failed!\r\n", io->stdErr); + return ERR_FAILED; + } + if (res != ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Failure reading memory block!\r\n", io->stdErr); + return ERR_FAULT; + } + /* write address */ + UTIL1_strcpy(str, sizeof(str), (unsigned char*)"0x"); + UTIL1_strcatNumHex(str, sizeof(str), addr, addrSize); + UTIL1_chcat(str, sizeof(str), ':'); + CLS1_SendStr((unsigned char*)str, io->stdOut); + /* write data in hex */ + str[0] = '\0'; + for (j=0; jstdOut); + /* write in ASCII */ + io->stdOut(' '); + for (j=0; j= ' ' && ch <= 0x7f) { + io->stdOut(ch); + } else { + io->stdOut('.'); /* place holder */ + } + } + for (/*empty*/; jstdOut); + addr += bytesPerLine; + } + return ERR_OK; +} + +/* END CLS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.h new file mode 100644 index 0000000..7c7977f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1.h @@ -0,0 +1,830 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:40, # CodeGen: 32 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD> " +** Project Name : SolderPaste Dispenser +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Disabled +** Utility : UTIL1 +** Default Serial : Enabled +** Console Interface : RTT1 +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + + +#ifndef __CLS1_H +#define __CLS1_H + +/* MODULE CLS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CLS1config.h" /* configuration */ + + +#ifndef __BWUserType_CLS1_StdIO_OutErr_FctType +#define __BWUserType_CLS1_StdIO_OutErr_FctType + typedef void (*CLS1_StdIO_OutErr_FctType)(uint8_t); /* Callback for an output or error I/O function */ +#endif +#ifndef __BWUserType_CLS1_StdIO_In_FctType +#define __BWUserType_CLS1_StdIO_In_FctType + typedef void (*CLS1_StdIO_In_FctType)(uint8_t *); /* Callback for an I/O input function. */ +#endif +#ifndef __BWUserType_CLS1_StdIO_KeyPressed_FctType +#define __BWUserType_CLS1_StdIO_KeyPressed_FctType + typedef bool (*CLS1_StdIO_KeyPressed_FctType)(void); /* Callback which returns true if a key has been pressed */ +#endif +#ifndef __BWUserType_CLS1_StdIOType +#define __BWUserType_CLS1_StdIOType + typedef struct { /* Record containing input, output and error callback (stdin, stdout, stderr). */ + CLS1_StdIO_In_FctType stdIn; /* standard input */ + CLS1_StdIO_OutErr_FctType stdOut; /* standard output */ + CLS1_StdIO_OutErr_FctType stdErr; /* standard error */ + CLS1_StdIO_KeyPressed_FctType keyPressed; /* key pressed callback */ + } CLS1_StdIOType; +#endif +#ifndef __BWUserType_CLS1_ConstStdIOType +#define __BWUserType_CLS1_ConstStdIOType + typedef const CLS1_StdIOType CLS1_ConstStdIOType; /* constant StdIOType */ +#endif +#ifndef __BWUserType_CLS1_ParseCommandCallback +#define __BWUserType_CLS1_ParseCommandCallback + typedef uint8_t (*CLS1_ParseCommandCallback)(const uint8_t *cmd, bool *handled, const CLS1_StdIOType *io); /* Callback for parsing a shell command */ +#endif +#ifndef __BWUserType_CLS1_ConstStdIOTypePtr +#define __BWUserType_CLS1_ConstStdIOTypePtr + typedef const CLS1_ConstStdIOType *CLS1_ConstStdIOTypePtr; /* Pointer to constant standard I/O descriptor */ +#endif +#ifndef __BWUserType_CLS1_ConstParseCommandCallback +#define __BWUserType_CLS1_ConstParseCommandCallback + typedef const CLS1_ParseCommandCallback CLS1_ConstParseCommandCallback; /* Callback for parsing a shell command */ +#endif + +#define CLS1_DEFAULT_SHELL_BUFFER_SIZE CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE /* default buffer size for shell command parsing */ + +/* Include inherited components */ + +/* other includes needed */ +#include /* for size_t */ + +/* settings for command line history */ +#define CLS1_HISTORY_ENABLED 0 /* 1: enabled, 0: disabled */ +#define CLS1_NOF_HISTORY 0 /* number of items in history */ +#define CLS1_HIST_LEN 0 /* history buffer size */ + +/* settings for silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR '#' /* with this char as first character in the cmd, printing is silent. Use a space to disable it */ +#define CLS1_NO_SILENT_PREFIX_CHAR ' ' /* used for no silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR_ENABLED (CLS1_SILENT_PREFIX_CHAR != CLS1_NO_SILENT_PREFIX_CHAR) + +/* settings for local echo */ +#define CLS1_ECHO_ENABLED 0 /* 1: enabled, 0: disabled */ + +#define CLS1_DEFAULT_SERIAL CLS1_CONFIG_DEFAULT_SERIAL /* If set to 1, then the shell implements its own StdIO which is returned by CLS1_GetStdio(); */ + +extern uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +#if CLS1_DEFAULT_SERIAL + extern CLS1_ConstStdIOType CLS1_stdio; /* default standard I/O */ +#endif + +#define CLS1_DASH_LINE "--------------------------------------------------------------" +/* predefined commands */ +#define CLS1_CMD_HELP "help" +#define CLS1_CMD_STATUS "status" + +#ifdef __cplusplus +extern "C" { +#endif + +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ + +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ + +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_Init(void); +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_RequestSerial(void); +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReleaseSerial(void); +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReadChar(uint8_t *c); +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_KeyPressed(void); +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Shell) +** +** Description : +** De-Initializes the module, especially frees the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void* CLS1_GetSemaphore(void); +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable); +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendData(const uint8_t *data, uint16_t dataSize, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendData (component Shell) +** +** Description : +** Sends data using an I/O function. Unlike SendStr(), with +** this method it is possible to send binary data, including +** zero bytes. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to be sent +** dataSize - Number of bytes to be sent. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev); +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ + +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +unsigned CLS1_printf(const char *fmt, ...); +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_printfPutChar(void *arg, char c); +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END CLS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __CLS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1config.h new file mode 100644 index 0000000..02a6859 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CLS1config.h @@ -0,0 +1,82 @@ +#ifndef __CLS1_CONFIG_H +#define __CLS1_CONFIG_H + +#ifndef CLS1_CONFIG_BLOCKING_SEND_ENABLED + #define CLS1_CONFIG_BLOCKING_SEND_ENABLED (1) + /*!< 1: Sending is blocking (with an optional timeout); 0: Do not block on sending */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (20) + /*!< Total blocking time (timeout) in milliseconds, uses 0 for blocking without a timeout */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS (5) + /*!< waiting time during blocking, use 0 (zero) for polling */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + #define CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT (1) + /*!< 1: Use WaitmsOS() instead of Waitms(); 0: Use Waitms() instead of WaitOSms() */ +#endif + +#ifndef CLS1_CONFIG_USE_MUTEX + #define CLS1_CONFIG_USE_MUTEX (0) + /*!< 1: use RTOS mutex; 0: do not use RTOS mutex */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE + #define CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE (48) + /*!< default buffer size for shell command parsing */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SERIAL + #define CLS1_CONFIG_DEFAULT_SERIAL (1) + /*!< 1: the shell implements its own StdIO which is returned by GetStdio(); 0: The shell does not implement its own standard I/O */ +#endif + +#if CLS1_CONFIG_DEFAULT_SERIAL + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE + #define CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE "RTT1.h" + /*!< Include for the functions below */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME RTT1_RecvChar + /*!< Function name to read a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME RTT1_SendChar + /*!< Function name to send a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME RTT1_GetCharsInRxBuf + /*!< Function name to check if there is anything available to receive and returns TRUE, otherwise FALSE */ + #endif +#endif + +#ifndef CLS1_CONFIG_PROMPT_STRING + #define CLS1_CONFIG_PROMPT_STRING "CMD> " +#endif + +#ifndef CLS1_CONFIG_PROJECT_NAME_STRING + #define CLS1_CONFIG_PROJECT_NAME_STRING "SolderPaste Dispenser" +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_ENABLED + #define CLS1_CONFIG_MULTI_CMD_ENABLED (0) /* 1: enabled, 0: disabled */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_SIZE + #define CLS1_CONFIG_MULTI_CMD_SIZE (32) /* max size of each command */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_CHAR + #define CLS1_CONFIG_MULTI_CMD_CHAR ';' /* separation character */ +#endif + + +#endif /* __CLS1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.c new file mode 100644 index 0000000..0c90511 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.c @@ -0,0 +1,151 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +/* MODULE CS1. */ + +#include "CS1.h" + +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_CriticalVariable(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_EnterCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_ExitCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Init(void) +{ + /* nothing needed */ +} + +/* END CS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.h new file mode 100644 index 0000000..f78b7f3 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1.h @@ -0,0 +1,216 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +#ifndef __CS1_H +#define __CS1_H + +/* MODULE CS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CS1config.h" /* configuration */ + + +/* other includes needed */ +#if CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #include "FreeRTOS.h" + #include "task.h" /* FreeRTOS header file for taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* workaround macros for wrong EnterCritical()/ExitCritical() in the low level drivers. */ +#define CS1_CriticalVariableDrv() \ + CS1_CriticalVariable() +#define CS1_EnterCriticalDrv() \ + CS1_EnterCritical() +#define CS1_ExitCriticalDrv() \ + CS1_ExitCritical() + +#ifdef __HIWARE__ + #pragma MESSAGE DISABLE C3303 /* C3303 Implicit concatenation of strings */ +#endif + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_CriticalVariable() /* nothing needed */ + #else + #define CS1_CriticalVariable() uint8_t cpuSR; /* variable to store current status */ + #endif +#endif +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_EnterCritical() EnterCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_EnterCritical() taskENTER_CRITICAL_FROM_ISR() /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_EnterCritical() \ + do { \ + __asm volatile( "csrc mstatus, 8" ); /* Disable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_EnterCritical() \ + do { \ + /*lint -save -esym(529,cpuSR) Symbol 'cpuSR' not subsequently referenced. */\ + __asm ( \ + "mrs r0, PRIMASK \n\t" \ + "cpsid i \n\t" \ + "strb r0, %[output] \n\t" \ + : [output] "=m" (cpuSR) :: "r0"); \ + __asm ("" ::: "memory"); \ + /*lint -restore Symbol 'cpuSR' not subsequently referenced. */\ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_ExitCritical() ExitCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_ExitCritical() taskEXIT_CRITICAL_FROM_ISR(0) /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_ExitCritical() \ + do { \ + __asm volatile( "csrs mstatus, 8" ); /* Enable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_ExitCritical() \ + do{ \ + __asm ( \ + "ldrb r0, %[input] \n\t" \ + "msr PRIMASK,r0 \n\t" \ + ::[input] "m" (cpuSR) : "r0"); \ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Init(void); +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END CS1. */ + +#ifdef __cplusplus +} +#endif + +#endif +/* ifndef __CS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/CS1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1config.h new file mode 100644 index 0000000..2fe3b70 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/CS1config.h @@ -0,0 +1,18 @@ +#ifndef __CS1_CONFIG_H +#define __CS1_CONFIG_H + +/* select ONE of the following implementation methods: */ +#ifndef CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CONFIG_USE_RTOS_CRITICAL_SECTION 0 /* 1: use FreeRTOS critical section; 0: don't use FreeRTOS critical sections */ +#endif + +#ifndef CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #define CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION 1 /* 1: Custom implementation (supported for GNU and ARM!); 0: don't use custom implementation */ +#endif + +#ifndef CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CONFIG_USE_PEX_DEFAULT 0 /* 1: use Processor Expert default; 0: use alternative implementation */ +#endif + +#endif /* __CS1_CONFIG_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.c new file mode 100644 index 0000000..7fc94bb --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.c @@ -0,0 +1,1476 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : MK20DX128FT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K20P48M50SF0RM Rev. 1, Oct 2011 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : Cpu +** CPU type : MK20DX128VFT5 +** CPU : CPU +** MemModelDev : MemModel_FlexMem +** Clock settings : +** Internal oscillator : +** Slow internal reference clock [kHz] : 32.768 +** Initialize slow trim value : no +** Fast internal reference clock [MHz] : 4 +** Initialize fast trim value : no +** RTC oscillator : Disabled +** System oscillator 0 : Enabled +** Clock source : External crystal +** Clock input pin : +** Pin name : EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 +** Pin signal : +** Clock output pin : +** Pin name : XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1 +** Pin signal : +** Clock frequency [MHz] : 8 +** Capacitor load : 0pF +** Oscillator operating mode : Low power +** Clock source settings : 1 +** Clock source setting 0 : +** Internal reference clock : +** MCGIRCLK clock : Enabled +** MCGIRCLK in stop : Disabled +** MCGIRCLK source : Slow +** MCGIRCLK clock [MHz] : 0.032768 +** External reference clock : +** OSC0ERCLK clock : Enabled +** OSC0ERCLK in stop : Disabled +** OSC0ERCLK clock [MHz] : 8 +** ERCLK32K clock source : Auto select +** ERCLK32K. clock [kHz] : 0.001 +** MCG settings : +** MCG mode : PEE +** MCG output clock : PLL clock +** MCG output [MHz] : 96 +** MCG external ref. clock source : System oscillator 0 +** MCG external ref. clock [MHz] : 8 +** Clock monitor : Disabled +** FLL settings : +** FLL module : Disabled +** FLL output [MHz] : 0 +** MCGFFCLK clock [kHz] : 31.25 +** Reference clock source : External clock +** Reference clock divider : Auto select +** FLL reference clock [kHz] : 31.25 +** Multiplication factor : Auto select +** PLL 0 settings : +** PLL module : Enabled +** PLL module in Stop : Disabled +** PLL output [MHz] : 96 +** Reference clock divider : Auto select +** PLL reference clock [MHz] : 4 +** Multiplication factor : Auto select +** Loss of lock interrupt : Disabled +** Initialization priority : minimal priority +** Watchdog disable : yes +** Internal peripherals : +** NMI pin : Enabled +** NMI Pin : TSI0_CH5/PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b +** NMI Pin signal : +** Reset control : Enabled +** Reset pin : RESET_b +** Reset pin signal : +** Filter in STOP : Disabled +** Filter in RUN/WAIT : Disabled +** Filter width : 1 +** Debug interface (JTAG) : +** JTAG Mode : JTAG +** TDI : Enabled +** TDI Pin : TSI0_CH2/PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI +** TDI Pin signal : +** TDO : Enabled +** TDO Pin : TSI0_CH3/PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO +** TDO Pin signal : +** TCK : Enabled +** TCK Pin : TSI0_CH1/PTA0/UART0_CTS_b/UART0_COL_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK +** TCK Pin signal : +** TMS : Enabled +** TMS Pin : TSI0_CH4/PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO +** TMS Pin signal : +** nTRST : Disabled +** Flash memory organization : +** FlexNVM settings : Partition code: 0xFFFF +** FlexNVM size : 32 KB +** DFlash size : 32 KB +** EEPROM size : 0 bytes +** Start : 0x10000000 +** Size : 0x0 +** Start : 0x14000000 +** Size : 0x0 +** FlexRAM : Disabled +** Flash blocks : 2 +** Flash block 0 : PFlash +** Address : 0x0 +** Size : 131072 +** Write unit size : 4 +** Erase unit size : 1024 +** Protection unit size : 4096 +** Flash block 1 : DFlash +** Address : 0x10000000 +** Size : 32768 +** Write unit size : 4 +** Erase unit size : 1024 +** Protection unit size : 4096 +** Flexible memory controller : Disabled +** Flash configuration field : Enabled +** Security settings : +** Flash security : Disabled +** Freescale failure analysis access : Enabled +** Mass erase : Enabled +** Backdoor key security : Disabled +** Backdoor key 0 : 255 +** Backdoor key 1 : 255 +** Backdoor key 2 : 255 +** Backdoor key 3 : 255 +** Backdoor key 4 : 255 +** Backdoor key 5 : 255 +** Backdoor key 6 : 255 +** Backdoor key 7 : 255 +** Protection regions : +** P-Flash protection settings : +** Protection region size : 4096 +** P-Flash protection : 0xFFFFFFFF +** Protection regions : +** Protection region 0 : Unprotected +** Protection region 1 : Unprotected +** Protection region 2 : Unprotected +** Protection region 3 : Unprotected +** Protection region 4 : Unprotected +** Protection region 5 : Unprotected +** Protection region 6 : Unprotected +** Protection region 7 : Unprotected +** Protection region 8 : Unprotected +** Protection region 9 : Unprotected +** Protection region 10 : Unprotected +** Protection region 11 : Unprotected +** Protection region 12 : Unprotected +** Protection region 13 : Unprotected +** Protection region 14 : Unprotected +** Protection region 15 : Unprotected +** Protection region 16 : Unprotected +** Protection region 17 : Unprotected +** Protection region 18 : Unprotected +** Protection region 19 : Unprotected +** Protection region 20 : Unprotected +** Protection region 21 : Unprotected +** Protection region 22 : Unprotected +** Protection region 23 : Unprotected +** Protection region 24 : Unprotected +** Protection region 25 : Unprotected +** Protection region 26 : Unprotected +** Protection region 27 : Unprotected +** Protection region 28 : Unprotected +** Protection region 29 : Unprotected +** Protection region 30 : Unprotected +** Protection region 31 : Unprotected +** D-Flash protection settings : +** Protection region size : 4096 +** D-Flash protection : 0xFF +** Protection regions : +** Protection region 0 : Unprotected +** Protection region 1 : Unprotected +** Protection region 2 : Unprotected +** Protection region 3 : Unprotected +** Protection region 4 : Unprotected +** Protection region 5 : Unprotected +** Protection region 6 : Unprotected +** Protection region 7 : Unprotected +** Eeprom protection settings : +** Protection region size : 0 +** Eeprom protection : 0xFF +** Protection regions : +** Protection region 0 : Unprotected +** Protection region 1 : Unprotected +** Protection region 2 : Unprotected +** Protection region 3 : Unprotected +** Protection region 4 : Unprotected +** Protection region 5 : Unprotected +** Protection region 6 : Unprotected +** Protection region 7 : Unprotected +** Peripheral settings : +** NMI function : Enabled +** EzPort operation at boot : Enabled +** Low power boot : Disabled +** System control block settings : Disabled +** Power management controller : +** LVD reset : Enabled +** LVD voltage treshold : Low +** LVW voltage treshold : Low +** Bandgap buffer : Disabled +** LVD interrupt : +** Interrupt : INT_LVD_LVW +** Interrupt request : Disabled +** Interrupt priority : 0 (Highest) +** LVD interrupt : Disabled +** LVW interrupt : Disabled +** System Integration Module : +** CLKOUT pin control : Disabled +** Clock gating control : Disabled +** CPU interrupts/resets : +** NMI interrupt : Enabled +** Interrupt : INT_NMI +** Hard Fault : Disabled +** Bus Fault : Disabled +** Usage Fault : Disabled +** Supervisor Call : Disabled +** Pendable Service : Disabled +** MCG : Disabled +** Low power mode settings : +** Allowed power modes : +** Very low power modes : Not allowed +** Low leakage stop mode : Not allowed +** Very low leakage stop mode : Not allowed +** LLWU settings : Disabled +** Operation mode settings : +** WAIT operation mode : +** Return to wait after ISR : no +** SLEEP operation mode : +** Return to stop after ISR : no +** STOP operation mode : Disabled +** Clock configurations : 1 +** Clock configuration 0 : +** __IRC_32kHz : 0.032768 +** __IRC_4MHz : 2 +** __SYSTEM_OSC : 8 +** __RTC_OSC : 0 +** Very low power mode : Disabled +** Clock source setting : configuration 0 +** MCG mode : PEE +** MCG output [MHz] : 96 +** MCGIRCLK clock [MHz] : 0.032768 +** OSCERCLK clock [MHz] : 8 +** ERCLK32K. clock [kHz] : 0.001 +** MCGFFCLK [kHz] : 31.25 +** System clocks : +** Core clock prescaler : Auto select +** Core clock : 48 +** Bus clock prescaler : Auto select +** Bus clock : 48 +** Flash clock prescaler : Auto select +** Flash clock : 24 +** PLL/FLL clock selection : PLL clock +** Clock frequency [MHz] : 96 +** Contents : +** EnableInt - void Cpu_EnableInt(void); +** DisableInt - void Cpu_DisableInt(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +/* MODULE Cpu. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "MCUC1.h" +#include "WAIT1.h" +#include "RTT1.h" +#include "CLS1.h" +#include "UTIL1.h" +#include "XF1.h" +#include "CS1.h" +#include "Step.h" +#include "BitIoLdd2.h" +#include "Dir.h" +#include "BitIoLdd4.h" +#include "MS2.h" +#include "BitIoLdd5.h" +#include "MS1.h" +#include "BitIoLdd6.h" +#include "MotEn.h" +#include "BitIoLdd7.h" +#include "MotSleep.h" +#include "BitIoLdd8.h" +#include "FRTOS1.h" +#include "USB1.h" +#include "CDC1.h" +#include "Tx1.h" +#include "Rx1.h" +#include "USB0.h" +#include "TMOUT1.h" +#include "HF1.h" +#include "TI1.h" +#include "TimerIntLdd1.h" +#include "TU1.h" +#include "KEY1.h" +#include "Inhr1.h" +#include "BitIoLdd9.h" +#include "TRG1.h" +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +#include "Events.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables */ +volatile uint8_t SR_reg; /* Current value of the FAULTMASK register */ +volatile uint8_t SR_lock = 0x00U; /* Lock */ + +/* +** =================================================================== +** Method : Cpu_SetBASEPRI (component MK20DX128FT5) +** +** Description : +** This method sets the BASEPRI core register. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void Cpu_SetBASEPRI(uint32_t Level); + +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK20DX128FT5) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_INT_NMIInterrupt) +{ + Cpu_OnNMIINT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Mem_Manage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Mem_Manage_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Bus_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Bus_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Usage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Usage_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved7 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved7) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved8 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved8) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved9 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved9) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved10 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved10) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DebugMonitor (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DebugMonitor) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved13 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved13) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA2) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA3) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA_Error (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA_Error) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved21 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved21) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTFL (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_FTFL) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Read_Collision (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Read_Collision) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LVD_LVW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LVD_LVW) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LLW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LLW) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Watchdog (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Watchdog) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2C0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2C0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SPI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_SPI0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Tx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2S0_Tx) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Rx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2S0_Rx) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_LON (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART0_LON) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART0_RX_TX) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART0_ERR) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART1_RX_TX) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART1_ERR) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART2_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART2_RX_TX) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART2_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART2_ERR) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_ADC0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_ADC0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMP0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMP1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_FTM1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMT (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMT) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_RTC) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC_Seconds (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_RTC_Seconds) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT2) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT3) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PDB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PDB0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USBDCD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_USBDCD) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_TSI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_TSI0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_MCG (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_MCG) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LPTimer (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LPTimer) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTA (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTA) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTB (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTB) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTC) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTD) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTE (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTE) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SWI (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_SWI) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_EnableInt (component MK20DX128FT5) +*/ +/*! +** @brief +** Enables all maskable interrupts. +*/ +/* ===================================================================*/ +void Cpu_EnableInt(void) +{ + __EI(); +} + +/* +** =================================================================== +** Method : Cpu_DisableInt (component MK20DX128FT5) +*/ +/*! +** @brief +** Disables all maskable interrupts. +*/ +/* ===================================================================*/ +void Cpu_DisableInt(void) +{ + __DI(); +} + + +/*** !!! Here you can place your own code using property "User data declarations" on the build options tab. !!! ***/ + +/*lint -esym(765,__init_hardware) Disable MISRA rule (8.10) checking for symbols (__init_hardware). The function is linked to the EWL library */ +/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ +void __init_hardware(void) +{ + + /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ + + /*** ### MK20DX128VFT5 "Cpu" init code ... ***/ + /*** PE initialization code after reset ***/ + SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ + /* Disable the WDOG module */ + /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ + WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ + /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ + WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ + /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ + WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | + WDOG_STCTRLH_WAITEN_MASK | + WDOG_STCTRLH_STOPEN_MASK | + WDOG_STCTRLH_ALLOWUPDATE_MASK | + WDOG_STCTRLH_CLKSRC_MASK | + 0x0100U; + + /* System clock initialization */ + /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | + SIM_CLKDIV1_OUTDIV2(0x01) | + SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ + /* SIM_SCGC5: PORTD=1,PORTA=1 */ + SIM_SCGC5 |= (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTA_MASK); /* Enable clock gate for ports to enable pin routing */ + if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { + /* PMC_REGSC: ACKISO=1 */ + PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ + } + /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=1,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) | + SIM_CLKDIV1_OUTDIV2(0x01) | + SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */ + /* SIM_SOPT2: PLLFLLSEL=1 */ + SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ + /* SIM_SOPT1: OSC32KSEL=3 */ + SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ + /* PORTA_PCR18: ISF=0,MUX=0 */ + PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); + /* PORTA_PCR19: ISF=0,MUX=0 */ + PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); + /* Switch to FBE Mode */ + /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ + MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); + /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ + OSC0_CR = OSC_CR_ERCLKEN_MASK; + /* MCG_C7: OSCSEL=0 */ + MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); + /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); + /* MCG_C4: DMX32=0,DRST_DRS=0 */ + MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); + /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ + MCG_C5 = MCG_C5_PRDIV0(0x01); + /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=0 */ + MCG_C6 = MCG_C6_VDIV0(0x00); + while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ + } + while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ + } + while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + /* Switch to PBE Mode */ + /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=0 */ + MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x00)); + while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ + } + /* Switch to PEE Mode */ + /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); + while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ + } + /*** End of PE initialization code after reset ***/ + + /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ + +} + +/* +** =================================================================== +** Method : Cpu_SetBASEPRI (component MK20DX128FT5) +** +** Description : +** This method sets the BASEPRI core register. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */ +#ifdef _lint + #define Cpu_SetBASEPRI(Level) /* empty */ +#else +void Cpu_SetBASEPRI(uint32_t Level) { + __asm ("msr basepri, %[input]"::[input] "r" (Level):); +} +#endif +/*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + + +/* +** =================================================================== +** Method : PE_low_level_init (component MK20DX128FT5) +** +** Description : +** Initializes beans and provides common register initialization. +** The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void PE_low_level_init(void) +{ + #ifdef PEX_RTOS_INIT + PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ + #endif + /* Initialization of the SIM module */ + /* PORTA_PCR4: ISF=0,MUX=7 */ + PORTA_PCR4 = (uint32_t)((PORTA_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK + )) | (uint32_t)( + PORT_PCR_MUX(0x07) + )); + /* Initialization of the RCM module */ + /* RCM_RPFW: RSTFLTSEL=0 */ + RCM_RPFW &= (uint8_t)~(uint8_t)(RCM_RPFW_RSTFLTSEL(0x1F)); + /* RCM_RPFC: RSTFLTSS=0,RSTFLTSRW=0 */ + RCM_RPFC &= (uint8_t)~(uint8_t)( + RCM_RPFC_RSTFLTSS_MASK | + RCM_RPFC_RSTFLTSRW(0x03) + ); + /* Initialization of the FTFL_FlashConfig module */ + /* Initialization of the PMC module */ + /* PMC_REGSC: ACKISO=0,BGBE=0 */ + PMC_REGSC &= (uint8_t)~(uint8_t)( + PMC_REGSC_ACKISO_MASK | + PMC_REGSC_BGBE_MASK + ); + /* PMC_LVDSC1: LVDACK=1,LVDIE=0,LVDRE=1,LVDV=0 */ + PMC_LVDSC1 = (uint8_t)((PMC_LVDSC1 & (uint8_t)~(uint8_t)( + PMC_LVDSC1_LVDIE_MASK | + PMC_LVDSC1_LVDV(0x03) + )) | (uint8_t)( + PMC_LVDSC1_LVDACK_MASK | + PMC_LVDSC1_LVDRE_MASK + )); + /* PMC_LVDSC2: LVWACK=1,LVWIE=0,LVWV=0 */ + PMC_LVDSC2 = (uint8_t)((PMC_LVDSC2 & (uint8_t)~(uint8_t)( + PMC_LVDSC2_LVWIE_MASK | + PMC_LVDSC2_LVWV(0x03) + )) | (uint8_t)( + PMC_LVDSC2_LVWACK_MASK + )); + /* SMC_PMPROT: ??=0,??=0,AVLP=0,??=0,ALLS=0,??=0,AVLLS=0,??=0 */ + SMC_PMPROT = 0x00U; /* Setup Power mode protection register */ + /* Common initialization of the CPU registers */ + /* NVICIP35: PRI35=0 */ + NVICIP35 = NVIC_IP_PRI35(0x00); + /* NVICIP8: PRI8=0 */ + NVICIP8 = NVIC_IP_PRI8(0x00); + MCUC1_Init(); /* ### McuLibConfig "MCUC1" init code ... */ + /* ### BitIO_LDD "BitIoLdd1" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd1_Init(NULL); + LED1_Init(); /* ### LED "LED1" init code ... */ + WAIT1_Init(); /* ### Wait "WAIT1" init code ... */ + RTT1_Init(); /* ### SeggerRTT "RTT1" init code ... */ + UTIL1_Init(); /* ### Utility "UTIL1" init code ... */ + XF1_Init(); /* ### XFormat "XF1" init code ... */ + CS1_Init(); /* ### CriticalSection "CS1" init code ... */ + CLS1_Init(); /* ### Shell "CLS1" init code ... */ + /* ### BitIO_LDD "BitIoLdd2" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd2_Init(NULL); + /* ### BitIO_LDD "BitIoLdd4" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd4_Init(NULL); + /* ### BitIO_LDD "BitIoLdd5" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd5_Init(NULL); + /* ### BitIO_LDD "BitIoLdd6" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd6_Init(NULL); + /* ### BitIO_LDD "BitIoLdd7" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd7_Init(NULL); + /* ### BitIO_LDD "BitIoLdd8" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd8_Init(NULL); + /* PEX_RTOS_INIT() is a macro should already have been called either from main() + or Processor Expert startup code. So we don't call it here again. */ + /* PEX_RTOS_INIT(); */ /* ### FreeRTOS "FRTOS1" init code ... */ + /* ### Timeout "TMOUT1" init code ... */ + TMOUT1_Init(); + Tx1_Init(); /* ### RingBuffer "Tx1" init code ... */ + Rx1_Init(); /* ### RingBuffer "Rx1" init code ... */ + /* ### Init_USB_OTG "USB0" init code ... */ + USB0_Init(); + + + (void)USB1_Init(); + HF1_Init(); /* ### HardFault "HF1" init code ... */ + /* ### TimerInt_LDD "TimerIntLdd1" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)TimerIntLdd1_Init(NULL); + /* ### TimerInt "TI1" init code ... */ + /* ### Trigger "TRG1" init code ... */ + TRG1_Init(); + /* ### BitIO_LDD "BitIoLdd9" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd9_Init(NULL); + /* ### Key "KEY1" init code ... */ + KEY1_Init(); +} + /* Flash configuration field */ + __attribute__ ((section (".cfmconfig"))) const uint8_t _cfm[0x10] = { + /* NV_BACKKEY3: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY2: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY1: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY0: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY7: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY6: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY5: KEY=0xFF */ + 0xFFU, + /* NV_BACKKEY4: KEY=0xFF */ + 0xFFU, + /* NV_FPROT3: PROT=0xFF */ + 0xFFU, + /* NV_FPROT2: PROT=0xFF */ + 0xFFU, + /* NV_FPROT1: PROT=0xFF */ + 0xFFU, + /* NV_FPROT0: PROT=0xFF */ + 0xFFU, + /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */ + 0x7EU, + /* NV_FOPT: ??=1,??=1,??=1,??=1,??=1,NMI_DIS=1,EZPORT_DIS=1,LPBOOT=1 */ + 0xFFU, + /* NV_FEPROT: EPROT=0xFF */ + 0xFFU, + /* NV_FDPROT: DPROT=0xFF */ + 0xFFU + }; + +/* END Cpu. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.h b/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.h new file mode 100644 index 0000000..40207b2 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Cpu.h @@ -0,0 +1,813 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : MK20DX128FT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K20P48M50SF0RM Rev. 1, Oct 2011 +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** +** Settings : +** +** Contents : +** EnableInt - void Cpu_EnableInt(void); +** DisableInt - void Cpu_DisableInt(void); +** +** (c) Freescale Semiconductor, Inc. +** 2004 All Rights Reserved +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.h +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +#ifndef __Cpu_H +#define __Cpu_H + +/* MODULE Cpu. */ +/*Include shared modules, which are used for whole project*/ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Active configuration define symbol */ +#define PEcfg_FLASH 1U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define Cpu_EnableInt_METHOD_ENABLED +#define Cpu_DisableInt_METHOD_ENABLED + +/* Events configuration constants - generated for all enabled component's events */ +#define Cpu_OnNMIINT_EVENT_ENABLED + +#define CPU_BUS_CLK_HZ 48000000U /* Initial value of the bus clock frequency in Hz */ +#define CPU_CORE_CLK_HZ 48000000U /* Initial value of the core/system clock frequency in Hz. */ + +#define CPU_CLOCK_CONFIG_NUMBER 0x01U /* Specifies number of defined clock configurations. */ + +#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0 48000000U /* Value of the bus clock frequency in the clock configuration 0 in Hz. */ +#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0 48000000U /* Value of the core/system clock frequency in the clock configuration 0 in Hz. */ + + +#define CPU_XTAL_CLK_HZ 8000000U /* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768U /* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000U /* Value of the fast internal oscillator clock frequency in Hz */ + +#define CPU_FAMILY_Kinetis /* Specification of the core type of the selected cpu */ +#define CPU_DERIVATIVE_MK20DX128FT5 /* Name of the selected cpu derivative */ +#define CPU_PARTNUM_MK20DX128VFT5 /* Part number of the selected cpu */ +#define CPU_LITTLE_ENDIAN /* The selected cpu uses little endian */ + +/* CPU frequencies in clock configuration 0 */ +#define CPU_CLOCK_CONFIG_0 0x00U /* Clock configuration 0 identifier */ +#define CPU_CORE_CLK_HZ_CONFIG_0 48000000UL /* Core clock frequency in clock configuration 0 */ +#define CPU_BUS_CLK_HZ_CONFIG_0 48000000UL /* Bus clock frequency in clock configuration 0 */ +#define CPU_FLEXBUS_CLK_HZ_CONFIG_0 0UL /* Flexbus clock frequency in clock configuration 0 */ +#define CPU_FLASH_CLK_HZ_CONFIG_0 24000000UL /* FLASH clock frequency in clock configuration 0 */ +#define CPU_USB_CLK_HZ_CONFIG_0 0UL /* USB clock frequency in clock configuration 0 */ +#define CPU_PLL_FLL_CLK_HZ_CONFIG_0 96000000UL /* PLL/FLL clock frequency in clock configuration 0 */ +#define CPU_MCGIR_CLK_HZ_CONFIG_0 32768UL /* MCG internal reference clock frequency in clock configuration 0 */ +#define CPU_OSCER_CLK_HZ_CONFIG_0 8000000UL /* System OSC external reference clock frequency in clock configuration 0 */ +#define CPU_ERCLK32K_CLK_HZ_CONFIG_0 1000UL /* External reference clock 32k frequency in clock configuration 0 */ +#define CPU_MCGFF_CLK_HZ_CONFIG_0 31250UL /* MCG fixed frequency clock */ + + +typedef struct { + uint32_t cpu_core_clk_hz; /* Core clock frequency in clock configuration */ + uint32_t cpu_bus_clk_hz; /* Bus clock frequency in clock configuration */ + uint32_t cpu_flexbus_clk_hz; /* Flexbus clock frequency in clock configuration */ + uint32_t cpu_flash_clk_hz; /* FLASH clock frequency in clock configuration */ + uint32_t cpu_usb_clk_hz; /* USB clock frequency in clock configuration */ + uint32_t cpu_pll_fll_clk_hz; /* PLL/FLL clock frequency in clock configuration */ + uint32_t cpu_mcgir_clk_hz; /* MCG internal reference clock frequency in clock configuration */ + uint32_t cpu_oscer_clk_hz; /* System OSC external reference clock frequency in clock configuration */ + uint32_t cpu_erclk32k_clk_hz; /* External reference clock 32k frequency in clock configuration */ + uint32_t cpu_mcgff_clk_hz; /* MCG fixed frequency clock */ +} TCpuClockConfiguration; + +/* The array of clock frequencies in configured clock configurations */ +extern const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER]; + + /* Interrupt vector table type definition */ + typedef void (*const tIsrFunc)(void); + typedef struct { + void * __ptr; + tIsrFunc __fun[0x3D]; + } tVectorTable; + + extern const tVectorTable __vect_table; + +/* Global variables */ +/*lint -esym(765,SR_reg) Disable MISRA rule (8.10) checking for symbols (SR_reg). The SR_reg is used in inline assembler. */ +extern volatile uint8_t SR_reg; /* Current FAULTMASK register */ +/*lint -esym(765,SR_lock) Disable MISRA rule (8.10) checking for symbols (SR_lock). The SR_reg is used in inline assembler. */ +extern volatile uint8_t SR_lock; + + +/* +** =================================================================== +** Method : Cpu_EnableInt (component MK20DX128FT5) +*/ +/*! +** @brief +** Enables all maskable interrupts. +*/ +/* ===================================================================*/ +void Cpu_EnableInt(void); + +/* +** =================================================================== +** Method : Cpu_DisableInt (component MK20DX128FT5) +*/ +/*! +** @brief +** Disables all maskable interrupts. +*/ +/* ===================================================================*/ +void Cpu_DisableInt(void); + +/* +** =================================================================== +** Method : PE_low_level_init (component MK20DX128FT5) +** +** Description : +** Initializes beans and provides common register initialization. +** The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void PE_low_level_init(void); + +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(Cpu_INT_NMIInterrupt); +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK20DX128FT5) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Mem_Manage_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Mem_Manage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Bus_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Bus_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Usage_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Usage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved7); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved7 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved8); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved8 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved9); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved9 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved10); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved10 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DebugMonitor); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DebugMonitor (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved13); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved13 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA2); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA3); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA_Error); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA_Error (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved21); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved21 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_FTFL); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTFL (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Read_Collision); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Read_Collision (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LVD_LVW); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LVD_LVW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LLW); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LLW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Watchdog); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Watchdog (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2C0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2C0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_SPI0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SPI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2S0_Tx); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Tx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2S0_Rx); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Rx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART0_LON); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_LON (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART0_RX_TX); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART0_ERR); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART1_RX_TX); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART1_ERR); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART2_RX_TX); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART2_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART2_ERR); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART2_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_ADC0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_ADC0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMP0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMP1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_FTM1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMT); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMT (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_RTC); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_RTC_Seconds); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC_Seconds (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT2); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT3); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PDB0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PDB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_USBDCD); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USBDCD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_TSI0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_TSI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_MCG); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_MCG (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LPTimer); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LPTimer (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTA); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTA (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTB); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTB (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTC); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTD); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTE); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTE (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_SWI); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SWI (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void __init_hardware(void); +/* +** =================================================================== +** Method : __init_hardware (component MK20DX128FT5) +** +** Description : +** Initializes the whole system like timing, external bus, etc. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +/* END Cpu. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* __Cpu_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.c new file mode 100644 index 0000000..96602d6 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Dir.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Dir +** Pin for I/O : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool Dir_GetVal(void); +** PutVal - void Dir_PutVal(bool Val); +** ClrVal - void Dir_ClrVal(void); +** SetVal - void Dir_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Dir.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Dir_module Dir module documentation +** @{ +*/ + +/* MODULE Dir. */ + +#include "Dir.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : Dir_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool Dir_GetVal(void) + +** This method is implemented as a macro. See Dir.h file. ** +*/ + +/* +** =================================================================== +** Method : Dir_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void Dir_PutVal(bool Val) + +** This method is implemented as a macro. See Dir.h file. ** +*/ + +/* +** =================================================================== +** Method : Dir_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void Dir_ClrVal(void) + +** This method is implemented as a macro. See Dir.h file. ** +*/ + +/* +** =================================================================== +** Method : Dir_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void Dir_SetVal(void) + +** This method is implemented as a macro. See Dir.h file. ** +*/ + +/* END Dir. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.h b/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.h new file mode 100644 index 0000000..278ac07 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Dir.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Dir.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Dir +** Pin for I/O : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool Dir_GetVal(void); +** PutVal - void Dir_PutVal(bool Val); +** ClrVal - void Dir_ClrVal(void); +** SetVal - void Dir_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Dir.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Dir_module Dir module documentation +** @{ +*/ + +#ifndef __Dir_H +#define __Dir_H + +/* MODULE Dir. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd4.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : Dir_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define Dir_GetVal() (BitIoLdd4_GetVal(BitIoLdd4_DeviceData)) + +/* +** =================================================================== +** Method : Dir_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define Dir_PutVal(Val) (BitIoLdd4_PutVal(BitIoLdd4_DeviceData, (Val))) + +/* +** =================================================================== +** Method : Dir_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define Dir_ClrVal() (BitIoLdd4_ClrVal(BitIoLdd4_DeviceData)) + +/* +** =================================================================== +** Method : Dir_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define Dir_SetVal() (BitIoLdd4_SetVal(BitIoLdd4_DeviceData)) + +/* END Dir. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __Dir_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.c new file mode 100644 index 0000000..c040f0a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.c @@ -0,0 +1,4689 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:40, # CodeGen: 32 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4 +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 200 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 100 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 7000 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 4: merge free blocks +** Static Allocation : Disabled +** User Memory Section : Enabled +** Heap Section Name : .m_data_20000000 +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Disabled +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + +/* MODULE FRTOS1. */ +#include "FRTOS1.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portTicks.h" /* interface to tick counter */ + +#include "UTIL1.h" +#if configHEAP_SCHEME_IDENTIFICATION + /* special variable identifying the used heap scheme */ + const uint8_t freeRTOSMemoryScheme = configUSE_HEAP_SCHEME; +#endif + + +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskStartScheduler(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskYIELD(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENTER_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskEXIT_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskDISABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspendAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelay(portTickType xTicksToDelay) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType xTimeIncrement) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE uxNewPriority) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ +/* +pVoid FRTOS1_pvPortMalloc(size_t xWantedSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vPortFree(void *pv) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCount(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +Tsize_t FRTOS1_xPortGetFreeHeapSize(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void *pvBuffer, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ +/* +void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Init(void) +{ + portDISABLE_ALL_INTERRUPTS(); /* disable all interrupts, they get enabled in vStartScheduler() */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* enable clocking for low power timer, otherwise vPortStopTickTimer() will crash. + Additionally, Percepio trace needs access to the timer early on. */ + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); +#endif + vPortStopTickTimer(); /* tick timer shall not run until the RTOS scheduler is started */ +#if configUSE_PERCEPIO_TRACE_HOOKS + McuPercepio_Startup(); /* Startup Percepio Trace. Need to do this before calling any RTOS functions. */ +#endif +} + +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ +/* +signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCountFromISR(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void *pvItemToQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreate(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ +/* +byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet , BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ +/* +TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void *const pvTimerID, TimerCallbackFunction_t pxCallbackFunction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ +/* +void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ +/* +uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t *pxQueueBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount, StaticSemaphore_t pxSempahoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ +/* +UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if configGENERATE_RUN_TIME_STATS +void FRTOS1_AppConfigureTimerForRuntimeStats(void) +{ +#if configGENERATE_RUN_TIME_STATS_USE_TICKS + /* nothing needed, the RTOS will initialize the tick counter */ +#else + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + FRTOS1_RunTimeCounter = 0; +#endif +} + +#endif /* configGENERATE_RUN_TIME_STATS */ +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void) +{ +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + return xTaskGetTickCountFromISR(); /* using RTOS tick counter */ + #else /* using timer counter */ + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + return FRTOS1_RunTimeCounter; + #endif +#else + return 0; /* dummy value */ +#endif +} + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ +/* END FRTOS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.h new file mode 100644 index 0000000..c2d7d2b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1.h @@ -0,0 +1,4304 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4 +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 200 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 100 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 7000 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 4: merge free blocks +** Static Allocation : Disabled +** User Memory Section : Enabled +** Heap Section Name : .m_data_20000000 +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Disabled +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + + +#ifndef __FRTOS1_H +#define __FRTOS1_H + +/* MODULE FRTOS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "FreeRTOSConfig.h" +#include "FRTOS1config.h" /* configuration file for component */ + +#if configUSE_SHELL + #include "McuShell.h" +#endif + +/* other includes needed */ +#include "FreeRTOS.h" +#include "task.h" /* task API */ +#include "semphr.h" /* semaphore API */ +#include "event_groups.h" /* event group API */ +#include "timers.h" /* timer module API */ +#include /* for size_t type */ + +#if configUSE_PERCEPIO_TRACE_HOOKS + #include "McuPercepio.h" /* Interface to Percepio Trace */ +#endif + +/* Macro for shell support */ +#define FRTOS1_PARSE_COMMAND_ENABLED (configUSE_SHELL) /* set to 1 if method ParseCommand() is present, 0 otherwise */ +#define FRTOS1_GENERATE_PEX_RTOS_MACROS 1 /* set to 1 to generate the RTOS macros PEX_RTOS_INIT() and PEX_RTOS_START() */ + +/* Macros used by Processor Expert */ +#if FRTOS1_GENERATE_PEX_RTOS_MACROS + #define PEX_RTOS_INIT() /* macro called from PE_low_level_init() */ \ + FRTOS1_Init(); + + #define PEX_RTOS_START() FRTOS1_vTaskStartScheduler() +#endif +/* macro to identify CPU: 0 for M0+ and 4 for M4 */ +#if configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 0 /* Cortex M0+ core */ +#elif configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 4 /* Cortex M4 core */ +#elif configCPU_FAMILY_IS_ARM_M7(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 7 /* Cortex M7 core */ +#endif + +/* Prototypes for interrupt service handlers */ +void vPortSVCHandler(void); +void vPortPendSVHandler(void); +void vPortTickHandler(void); + +/* Version of Processor Expert (variable VersionOfPEx): 1313 */ + +#ifndef __BWUserType_Tsize_t +#define __BWUserType_Tsize_t + typedef size_t Tsize_t; /* Alias to size_t standard type */ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define FRTOS1_xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) \ + xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ + +#define FRTOS1_vTaskStartScheduler() \ + vTaskStartScheduler() +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskYIELD() \ + taskYIELD() +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENTER_CRITICAL() \ + taskENTER_CRITICAL() +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskEXIT_CRITICAL() \ + taskEXIT_CRITICAL() +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskDISABLE_INTERRUPTS() \ + taskDISABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENABLE_INTERRUPTS() \ + taskENABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspendAll() \ + vTaskSuspendAll() +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeAll() \ + xTaskResumeAll() +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_vTaskDelay(xTicksToDelay) \ + vTaskDelay(xTicksToDelay) +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) \ + vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxTaskPriorityGet(pxTask) \ + uxTaskPriorityGet(pxTask) +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ + +#define FRTOS1_vTaskPrioritySet(pxTask, uxNewPriority) \ + vTaskPrioritySet(pxTask, uxNewPriority) +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeRecursive(xMutex, xBlockTime) \ + xSemaphoreTakeRecursive(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveRecursive(xMutex) \ + xSemaphoreGiveRecursive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutex() \ + xSemaphoreCreateRecursiveMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspend(pxTaskToSuspend) \ + vTaskSuspend(pxTaskToSuspend) + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskResume(pxTaskToResume) \ + vTaskResume(pxTaskToResume) + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutex() \ + xSemaphoreCreateMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTake(xMutex, xBlockTime) \ + xSemaphoreTake(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGive(xMutex) \ + xSemaphoreGive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreCreateBinary(xSemaphore) \ + vSemaphoreCreateBinary(xSemaphore) + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) \ + xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreDelete(xSemaphore) \ + vSemaphoreDelete(xSemaphore) +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskList(pcWriteBuffer, bufSize) \ + vTaskList(pcWriteBuffer, bufSize) + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvPortMalloc(xWantedSize) \ + pvPortMalloc(xWantedSize) +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ + +#define FRTOS1_vPortFree(pv) \ + vPortFree(pv) +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCount() \ + xTaskGetTickCount() +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ + +#define FRTOS1_xTaskGetSchedulerState() \ + xTaskGetSchedulerState() +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetStackHighWaterMark(xTask) \ + uxTaskGetStackHighWaterMark(xTask) +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetNumberOfTasks() \ + uxTaskGetNumberOfTasks() +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ + +#define FRTOS1_xPortGetFreeHeapSize() \ + xPortGetFreeHeapSize() + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xQueueCreate(uxQueueLength, uxItemSize) \ + xQueueCreate(uxQueueLength, uxItemSize) +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceive(xQueue, pvBuffer, xTicksToWait) \ + xQueueReceive(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeek(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeek(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_vQueueDelete(pxQueueToDelete) \ + vQueueDelete(pxQueueToDelete) +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaiting(xQueue) \ + uxQueueMessagesWaiting(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaitingfromISR(xQueue) \ + uxQueueMessagesWaitingfromISR(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) \ + xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) \ + xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeFromISR(pxTaskToResume) \ + xTaskResumeFromISR(pxTaskToResume) + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xQueueReset(xQueue) \ + xQueueReset(xQueue) + +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGetMutexHolder(xSemaphore) \ + xSemaphoreGetMutexHolder(xSemaphore) + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +void FRTOS1_Init(void); +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetCurrentTaskHandle() \ + xTaskGetCurrentTaskHandle() +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ + +#define FRTOS1_xTaskGetIdleTaskHandle() \ + xTaskGetIdleTaskHandle() +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetTaskName(xTaskToQuery) \ + pcTaskGetTaskName(xTaskToQuery) +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCountFromISR() \ + xTaskGetTickCountFromISR() +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwrite(xQueue, pvItemToQueue) \ + xQueueOverwrite(xQueue, pvItemToQueue) +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_vQueueAddToRegistry(xQueue, pcQueueName) \ + vQueueAddToRegistry(xQueue, pcQueueName) +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vQueueUnregisterQueue(xQueue) \ + vQueueUnregisterQueue(xQueue) +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueFullFromISR(xQueue) \ + xQueueIsQueueFullFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueEmptyFromISR(xQueue) \ + xQueueIsQueueEmptyFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreate() \ + xEventGroupCreate() +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) \ + xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBits(xEventGroup, uxBitsToSet) \ + xEventGroupSetBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) \ + xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBits(xEventGroup, uxBitsToSet) \ + xEventGroupClearBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) \ + xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBits(xEventGroup) \ + xEventGroupGetBits(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBitsFromISR(xEventGroup) \ + xEventGroupGetBitsFromISR(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) \ + xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) \ + xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerIsTimerActive(xTimer) \ + xTimerIsTimerActive(xTimer) +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerStart(xTimer, xBlockTime) \ + xTimerStart(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStop(xTimer, xBlockTime) \ + xTimerStop(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) \ + xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerDelete(xTimer, xBlockTime) \ + xTimerDelete(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerReset(xTimer, xBlockTime) \ + xTimerReset(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) \ + xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_pvTimerGetTimerID(xTimer) \ + pvTimerGetTimerID(xTimer) +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ + +#define FRTOS1_xTimerGetTimerDaemonTaskHandle() \ + xTimerGetTimerDaemonTaskHandle() +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ + +#define FRTOS1_pcTimerGetTimerName(xTimer) \ + pcTimerGetTimerName(xTimer) +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) \ + xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) \ + xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyGive(xTaskToNotify) \ + xTaskNotifyGive(xTaskToNotify) \ +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ + +#define FRTOS1_ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) \ + ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ + +#define FRTOS1_vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) \ + vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskNotify(xTaskToNotify, ulValue, eAction) \ + xTaskNotify(xTaskToNotify, ulValue, eAction) +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) \ + xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) \ + xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ + +#define FRTOS1_vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) \ + vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) \ + pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinary() \ + xSemaphoreCreateBinary() +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) \ + xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) \ + xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyStateClear(xTask) \ + xTaskNotifyStateClear(xTask) +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +void FRTOS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetHandle(pcNameToQuery) \ + xTaskGetHandle(pcNameToQuery) + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetName(xTaskToQuery) \ + pcTaskGetName(xTaskToQuery) + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ + +#define FRTOS1_xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) \ + xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ + +#define FRTOS1_xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) \ + xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreateStatic(pxEventGroupBuffer) \ + xEventGroupCreateStatic(pxEventGroupBuffer) + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) \ + xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) \ + xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateMutexStatic(pxMutexBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) \ + vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxSemaphoreGetCount(xSemaphore) \ + uxSemaphoreGetCount(xSemaphore) +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +void FRTOS1_AppConfigureTimerForRuntimeStats(void); +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ + +/* END FRTOS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __FRTOS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1config.h new file mode 100644 index 0000000..778c867 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FRTOS1config.h @@ -0,0 +1,155 @@ +#ifndef __FRTOS1_CONFIG_H +#define __FRTOS1_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ + +/* -------------------------------------------------------------------- */ +/* Macros to identify the compiler used: */ +#define configCOMPILER_ARM_GCC 1 /* GNU ARM gcc compiler */ +#define configCOMPILER_ARM_IAR 2 /* IAR ARM compiler */ +#define configCOMPILER_ARM_FSL 3 /* Legacy Freescale ARM compiler */ +#define configCOMPILER_ARM_KEIL 4 /* ARM/Keil compiler */ +#define configCOMPILER_S08_FSL 5 /* Freescale HCS08 compiler */ +#define configCOMPILER_S12_FSL 6 /* Freescale HCS12(X) compiler */ +#define configCOMPILER_CF1_FSL 7 /* Freescale ColdFire V1 compiler */ +#define configCOMPILER_CF2_FSL 8 /* Freescale ColdFire V2 compiler */ +#define configCOMPILER_DSC_FSL 9 /* Freescale DSC compiler */ + +#define configCOMPILER configCOMPILER_ARM_GCC +/* -------------------------------------------------------------------- */ +/* CPU family identification */ +#define configCPU_FAMILY_S08 1 /* S08 core */ +#define configCPU_FAMILY_S12 2 /* S12(X) core */ +#define configCPU_FAMILY_CF1 3 /* ColdFire V1 core */ +#define configCPU_FAMILY_CF2 4 /* ColdFire V2 core */ +#define configCPU_FAMILY_DSC 5 /* 56800/DSC */ +#define configCPU_FAMILY_ARM_M0P 6 /* ARM Cortex-M0+ */ +#define configCPU_FAMILY_ARM_M3 7 /* ARM Cortex-M3 */ +#define configCPU_FAMILY_ARM_M4 8 /* ARM Cortex-M4 */ +#define configCPU_FAMILY_ARM_M4F 9 /* ARM Cortex-M4F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M7 10 /* ARM Cortex-M7 */ +#define configCPU_FAMILY_ARM_M7F 11 /* ARM Cortex-M7F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M33 12 /* ARM Cortex-M33 */ +#define configCPU_FAMILY_ARM_M33F 13 /* ARM Cortex-M33F (with floating point unit) */ +#define configCPU_FAMILY_RISC_V 14 /* RISC-V */ + +/* Macros to identify set of core families */ +#define configCPU_FAMILY_IS_ARM_M0(fam) ((fam)==configCPU_FAMILY_ARM_M0P) +#define configCPU_FAMILY_IS_ARM_M3(fam) ((fam)==configCPU_FAMILY_ARM_M3) +#define configCPU_FAMILY_IS_ARM_M4(fam) (((fam)==configCPU_FAMILY_ARM_M4) || ((fam)==configCPU_FAMILY_ARM_M4F)) +#define configCPU_FAMILY_IS_ARM_M7(fam) (((fam)==configCPU_FAMILY_ARM_M7) || ((fam)==configCPU_FAMILY_ARM_M7F)) +#define configCPU_FAMILY_IS_ARM_M4_M7(fam) (configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam)) +#define configCPU_FAMILY_IS_ARM_M33(fam) (((fam)==configCPU_FAMILY_ARM_M33) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM_FPU(fam) (((fam)==configCPU_FAMILY_ARM_M4F) || ((fam)==configCPU_FAMILY_ARM_M7F) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM(fam) (configCPU_FAMILY_IS_ARM_M0(fam) || configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam) || configCPU_FAMILY_IS_ARM_M33(fam)) + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* determine core based on library configuration */ + #if MCUC1_CONFIG_CORTEX_M==0 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M0P + #elif MCUC1_CONFIG_CORTEX_M==3 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M3 + #elif MCUC1_CONFIG_CORTEX_M==4 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4F + #elif MCUC1_CONFIG_CORTEX_M==4 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4 + #elif MCUC1_CONFIG_CORTEX_M==7 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7F + #elif MCUC1_CONFIG_CORTEX_M==7 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7 + #elif MCUC1_CONFIG_CORTEX_M==33 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33F + #elif MCUC1_CONFIG_CORTEX_M==33 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33 + #else + #error "unsupported configuaration!" + #endif +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configCPU_FAMILY configCPU_FAMILY_RISC_V +#else /* default CPU family */ + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4 +#endif + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0 && (configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY)||configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY))) + /*!< 1: enable MPU support; 0: MPU support is disabled */ +#endif + +#ifndef configENABLE_FPU + #define configENABLE_FPU (1 && MCUC1_CONFIG_FPU_PRESENT) + /*!< 1: enable FPU support; 0: FPU support is disabled */ +#endif + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0 && configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) + /*!< 1: enable ARM TrustZone support; 0: TrustZone support is disabled */ +#endif + +/*----------------------------------------------------------- + * GDB backtrace handler support + * See http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + *----------------------------------------------------------*/ +#ifndef configGDB_HELPER + #define configGDB_HELPER (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GDB stack backtrace debug helper; 0: disabled */ +#endif + +#ifndef configLTO_HELPER + #define configLTO_HELPER (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GNU Link Time Optimizer (-lto) debug helper code; 0: disabled */ +#endif + +#ifndef configHEAP_SCHEME_IDENTIFICATION + #define configHEAP_SCHEME_IDENTIFICATION (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: use constant freeRTOSMemoryScheme to identify memory scheme; 0: no constant used */ +#endif + +#ifndef configUSE_TOP_USED_PRIORITY + #define configUSE_TOP_USED_PRIORITY (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: Makes sure uxTopUsedPriority is present (needed for SEGGER and OpenOCD thread aware debugging); 0: no special reference to uxTopUsedPriority */ +#endif + +#ifndef configLINKER_HEAP_BASE_SYMBOL + #define configLINKER_HEAP_BASE_SYMBOL __HeapBase + /*!< Linker symbol used to denote the base address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapBase, MCUXpresso: _pvHeapStart) */ +#endif + +#ifndef configLINKER_HEAP_LIMIT_SYMBOL + #define configLINKER_HEAP_LIMIT_SYMBOL __HeapLimit + /*!< Linker symbol used to denote the limit address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapLimit, MCUXpresso: _pvHeapLimit) */ +#endif + +#ifndef configLINKER_HEAP_SIZE_SYMBOL + #define configLINKER_HEAP_SIZE_SYMBOL __heap_size + /*!< Linker symbol used to denote the size of the heap, used for heap memory scheme 6 (newlib). (KDS: __heap_size, MCUXpresso: _HeapSize) */ +#endif + +#ifndef configUSE_SHELL + #define configUSE_SHELL (0) + /*!< 1: enable Shell and command line support; 0: disabled */ +#endif + +#ifndef configRESET_MSP + #define configRESET_MSP (1) + /*!< 1: reset MSP at scheduler start (Cortex M3/M4/M7 only); 0: do not reset MSP */ +#endif + + +/*----------------------------------------------------------- + * FreeRTOS Trace hook support + *----------------------------------------------------------- */ +#ifndef configUSE_PERCEPIO_TRACE_HOOKS + #define configUSE_PERCEPIO_TRACE_HOOKS 0 /* 1: Percepio Trace hooks, 0: not using Percepio Trace hooks */ +#endif +#define configUSE_TRACE_HOOKS configUSE_PERCEPIO_TRACE_HOOKS /* legacy configUSE_TRACE_HOOKS should not be used any more */ + +#ifndef configUSE_SEGGER_SYSTEM_VIEWER_HOOKS + #define configUSE_SEGGER_SYSTEM_VIEWER_HOOKS 0 /* 1: Segger System Viewer hooks, 0: not using Segger System Viewer hooks */ +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configUSE_PERCEPIO_TRACE_HOOKS + #error "only one trace method can be active!" +#endif +/*----------------------------------------------------------- */ + +#endif /* __FRTOS1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FSL_USB_Stack_Config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/FSL_USB_Stack_Config.h new file mode 100644 index 0000000..72657ff --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FSL_USB_Stack_Config.h @@ -0,0 +1,12 @@ +/****************************************************************************** + * Configuration file for the FSL USB stack created with Processor Expert. + *****************************************************************************/ +#ifndef __FSL_USB_STACK_CONFIG_ +#define __FSL_USB_STACK_CONFIG_ + +/* Overwrite initialization values from Processor Expert Init() component. These are 'known working values'. + * Otherwise you have to setup the bits (e.g. Pull-up/pull-down resistors! + * */ +#define USB_USER_CONFIG_USE_STACK_INIT 1 /* value set by component property 'Use USB Stack Initialization' */ + +#endif /* __FSL_USB_STACK_CONFIG_ */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS.h b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS.h new file mode 100644 index 0000000..ec88675 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS.h @@ -0,0 +1,1320 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +//#include /* READ COMMENT ABOVE. */ /*<< EST */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +// #include /* READ COMMENT ABOVE. */ /* << EST */ +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "SIM_PDD.h" /*! \todo this is a PEx header */ +#endif + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + #include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 + #define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +#ifndef portMEMORY_BARRIER + #define portMEMORY_BARRIER() +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + #include "SEGGER_SYSVIEW_FreeRTOS.h" /* include Segger System Viewer macro definitions */ +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H + #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#if 1 /* << EST additional trace entries used by Segger SystemView */ + +#ifndef traceISR_ENTER + #define traceISR_ENTER() +#endif + +#ifndef traceISR_EXIT_TO_SCHEDULER + #define traceISR_EXIT_TO_SCHEDULER() +#endif + +#ifndef traceISR_EXIT + #define traceISR_EXIT() +#endif + +#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST + #define traceMOVED_TASK_TO_SUSPENDED_LIST(x) +#endif + +#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST + #define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() +#endif + +#ifndef traceMOVED_TASK_TO_DELAYED_LIST + #define traceMOVED_TASK_TO_DELAYED_LIST() +#endif + +#endif /* << EST */ + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING + #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portALLOCATE_SECURE_CONTEXT + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) +#endif + +#ifndef portDONT_DISCARD + #define portDONT_DISCARD +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configUSE_POSIX_ERRNO + #define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#ifndef configSTACK_DEPTH_TYPE + /* Defaults to uint16_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if uint16_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE + /* Defaults to size_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if lengths will always be less than the number of bytes + in a size_t. */ + #define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #if( INCLUDE_vTaskSuspend != 1 ) + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT + #define configINITIAL_TICK_COUNT 0 +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or + portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + /* The tick type can be read atomically, so critical sections used when the + tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF + /* configPRINTF() was not defined, so define it away to nothing. To use + configPRINTF() then define it as follows (where MyPrintFunction() is + provided by the application writer): + + void MyPrintFunction(const char *pcFormat, ... ); + #define configPRINTF( X ) MyPrintFunction X + + Then call like a standard printf() function, but placing brackets around + all parameters so they are passed as a single parameter. For example: + configPRINTF( ("Value = %d", MyVariable) ); */ + #define configPRINTF( X ) +#endif + +#ifndef configMAX + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t + + /* For libraries that break the list data hiding, and access list structure + members directly (which is not supposed to be done). */ + #define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_MPU + #define configENABLE_MPU 0 +#endif + +/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif + +/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. +This is currently used in ARMv8M ports. */ +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE 1 +#endif + +/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on +the Secure Side only. */ +#ifndef configRUN_FREERTOS_SECURE_ONLY + #define configRUN_FREERTOS_SECURE_ONLY 0 +#endif + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using + * dynamically allocated RAM, in which case when any task is deleted it is known + * that both the task's stack and TCB need to be freed. Sometimes the + * FreeRTOSConfig.h settings only allow a task to be created using statically + * allocated RAM, in which case when any task is deleted it is known that neither + * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h + * settings allow a task to be created using either statically or dynamically + * allocated RAM, in which case a member of the TCB is used to record whether the + * stack and/or TCB were allocated statically or dynamically, so when a task is + * deleted the RAM that was allocated dynamically is freed again and no attempt is + * made to free the RAM that was allocated statically. + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a + * task to be created using either statically or dynamically allocated RAM. Note + * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with + * a statically allocated stack and a dynamically allocated TCB. + * + * The following table lists various combinations of portUSING_MPU_WRAPPERS, + * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and + * when it is possible to have both static and dynamic allocation: + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | + * | | | | | | Static Possible | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | + * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ + ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 4 ]; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; + #endif +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + UBaseType_t uxDummy2; + void *pvDummy3; + StaticMiniListItem_t xDummy4; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; + #endif +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; + #endif + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void *pvDummy5; + TaskFunction_t pvDummy6; + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + uint8_t ucDummy8; + +} StaticTimer_t; + +/* +* In line with software engineering best practice, especially when supplying a +* library that is likely to change in future versions, FreeRTOS implements a +* strict data hiding policy. This means the stream buffer structure used +* internally by FreeRTOS is not accessible to application code. However, if +* the application writer wants to statically allocate the memory required to +* create a stream buffer then the size of the stream buffer object needs to be +* know. The StaticStreamBuffer_t structure below is provided for this purpose. +* Its size and alignment requirements are guaranteed to match those of the +* genuine structure, no matter which architecture is being used, and no matter +* how the values in FreeRTOSConfig.h are set. Its contents are somewhat +* obfuscated in the hope users will recognise that it would be unwise to make +* direct use of the structure members. +*/ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* << EST */ + #include "trcRecorder.h" +#endif + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOSConfig.h b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOSConfig.h new file mode 100644 index 0000000..6132946 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOSConfig.h @@ -0,0 +1,305 @@ +/* + * FreeRTOS Kernel V10.1.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ +#include "FRTOS1config.h" /* extra configuration settings not part of the original FreeRTOS ports */ + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 /* 1: include additional header file at the end of task.c to help with debugging in GDB in combination with configUSE_TRACE_FACILITY; 0: no extra file included. */ +#define configENABLE_BACKWARD_COMPATIBILITY 0 /* 1: enable backward compatibility mode, using old names in kernel. 0: use new kernel structure names (recommended) */ +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ +#ifndef configGENERATE_RUN_TIME_STATS_USE_TICKS + #define configGENERATE_RUN_TIME_STATS_USE_TICKS 0 /* 1: Use the RTOS tick counter as runtime counter. 0: use extra timer */ +#endif +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 /* 1: generate runtime statistics; 0: no runtime statistics */ +#endif +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ /* default: use Tick counter as runtime counter */ + #define portGET_RUN_TIME_COUNTER_VALUE() xTaskGetTickCountFromISR() /* default: use Tick counter as runtime counter */ + #else /* use dedicated timer */ + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() FRTOS1_AppConfigureTimerForRuntimeStats() + #define portGET_RUN_TIME_COUNTER_VALUE() FRTOS1_AppGetRuntimeCounterValueFromISR() + #endif +#else /* no runtime stats, use empty macros */ + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ + #define portGET_RUN_TIME_COUNTER_VALUE() /* nothing */ +#endif +#define configUSE_PREEMPTION 1 /* 1: pre-emptive mode; 0: cooperative mode */ +#define configUSE_TIME_SLICING 1 /* 1: use time slicing; 0: don't time slice at tick interrupt time */ +#define configUSE_IDLE_HOOK 1 /* 1: use Idle hook; 0: no Idle hook */ +#define configUSE_IDLE_HOOK_NAME FRTOS1_vApplicationIdleHook +#define configUSE_TICK_HOOK 1 /* 1: use Tick hook; 0: no Tick hook */ +#define configUSE_TICK_HOOK_NAME FRTOS1_vApplicationTickHook +#define configUSE_MALLOC_FAILED_HOOK 1 /* 1: use MallocFailed hook; 0: no MallocFailed hook */ +#define configUSE_MALLOC_FAILED_HOOK_NAME FRTOS1_vApplicationMallocFailedHook +#ifndef configTICK_RATE_HZ + #define configTICK_RATE_HZ (100) /* frequency of tick interrupt */ +#endif +#define configSYSTICK_USE_LOW_POWER_TIMER 0 /* If using Kinetis Low Power Timer (LPTMR) instead of SysTick timer */ +#define configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ 1 /* 1 kHz LPO timer. Set to 1 if not used */ +#if MCUC1_CONFIG_NXP_SDK_USED || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_GENERIC || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_NORDIC_NRF5 +/* The CMSIS variable SystemCoreClock contains the current clock speed */ + extern uint32_t SystemCoreClock; + #define configCPU_CLOCK_HZ SystemCoreClock /* CPU clock frequency */ + #define configBUS_CLOCK_HZ SystemCoreClock /* Bus clock frequency */ +#else + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) /* Kinetis defines this one in Cpu.h */ + #define configCPU_CLOCK_HZ CPU_CORE_CLK_HZ /* CPU core clock defined in Cpu.h */ + #else + #define configCPU_CLOCK_HZ CPU_INSTR_CLK_HZ /* CPU core clock defined in Cpu.h */ + #endif + #define configBUS_CLOCK_HZ CPU_BUS_CLK_HZ /* CPU bus clock defined in Cpu.h */ +#endif /* #if MCUC1_CONFIG_NXP_SDK_USED */ +#define configSYSTICK_USE_CORE_CLOCK 1 /* System Tick is using core clock */ +#define configSYSTICK_CLOCK_DIVIDER 1 /* no divider */ +#define configSYSTICK_CLOCK_HZ ((configCPU_CLOCK_HZ)/configSYSTICK_CLOCK_DIVIDER) /* frequency of system tick counter */ +#ifndef configMINIMAL_STACK_SIZE + #define configMINIMAL_STACK_SIZE (200) /* stack size in addressable stack units */ +#endif +/*----------------------------------------------------------*/ +/* Heap Memory */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 4 /* either 1 (only alloc), 2 (alloc/free), 3 (malloc), 4 (coalesc blocks), 5 (multiple blocks), 6 (newlib) */ +#endif /* configUSE_HEAP_SCHEME */ +#define configFRTOS_MEMORY_SCHEME configUSE_HEAP_SCHEME /* for backwards compatible only with legacy name */ +#ifndef configTOTAL_HEAP_SIZE + #define configTOTAL_HEAP_SIZE (7000) /* size of heap in bytes */ +#endif /* configTOTAL_HEAP_SIZE */ +#ifndef configUSE_HEAP_SECTION_NAME + #define configUSE_HEAP_SECTION_NAME 1 /* set to 1 if a custom section name (configHEAP_SECTION_NAME_STRING) shall be used, 0 otherwise */ +#endif +#ifndef configHEAP_SECTION_NAME_STRING + #define configHEAP_SECTION_NAME_STRING ".m_data_20000000" /* heap section name (use e.g. ".m_data_20000000" for gcc and "m_data_20000000" for IAR). Check your linker file for the name used. */ +#endif +#define configAPPLICATION_ALLOCATED_HEAP 0 /* set to one if application is defining heap ucHeap[] variable, 0 otherwise */ +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* 1: make dynamic allocation functions for RTOS available. 0: only static functions are allowed */ +#endif +#ifndef configSUPPORT_STATIC_ALLOCATION + #define configSUPPORT_STATIC_ALLOCATION 0 /* 1: make static allocation functions for RTOS available. 0: only dynamic functions are allowed */ +#endif +#define configUSE_NEWLIB_REENTRANT (configUSE_HEAP_SCHEME==6) /* 1: a newlib reent structure will be allocated for each task; 0: no such reentr structure used */ +/*----------------------------------------------------------*/ +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 12 /* task name length in bytes */ +#endif +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 1 /* 1: include additional structure members and functions to assist with execution visualization and tracing, 0: no runtime stats/trace */ +#endif +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS (configUSE_TRACE_FACILITY || configGENERATE_RUN_TIME_STATS) +#endif +#define configUSE_16_BIT_TICKS 0 /* 1: use 16bit tick counter type, 0: use 32bit tick counter type */ +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 /* 1: the IDEL task will yield as soon as possible. 0: The IDLE task waits until preemption. */ +#endif +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION (1 && configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY)) /* 1: the scheduler uses an optimized task selection as defined by the port (if available). 0: normal task selection is used */ +#endif +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 1 +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 1 /* 0 is disabling stack overflow. Set it to 1 for Method1 or 2 for Method2 */ +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW_NAME + #define configCHECK_FOR_STACK_OVERFLOW_NAME FRTOS1_vApplicationStackOverflowHook +#endif +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 1 +#endif +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 5 +#endif +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 1 +#endif +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif +/* Tickless Idle Mode ----------------------------------------------------------*/ +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 /* set to 1 for tickless idle mode, 0 otherwise */ +#endif +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 /* number of ticks must be larger than this to enter tickless idle mode */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK + #define configUSE_TICKLESS_IDLE_DECISION_HOOK 0 /* set to 1 to enable application hook, zero otherwise */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME + #define configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME xEnterTicklessIdle /* function name of decision hook */ +#endif +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 /* number of tread local storage pointers, 0 to disable functionality */ +#endif + +#ifndef configMAX_PRIORITIES + #define configMAX_PRIORITIES 6 /* task priorities can be from 0 up to this value-1 */ +#endif +#define configMAX_CO_ROUTINE_PRIORITIES 2 /* co-routine priorities can be from 0 up to this value-1 */ + +/* the following needs to be defined (present) or not (not present)! */ +#define configTASK_RETURN_ADDRESS 0 /* return address of task is zero */ + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 1 /* 1: record stack high address for the debugger, 0: do not record stack high address */ +#endif + +/* Software timer definitions. */ +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_TASK_PRIORITY + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_QUEUE_LENGTH + #define configTIMER_QUEUE_LENGTH 10U /* size of queue for the timer task */ +#endif +#ifndef configTIMER_TASK_STACK_DEPTH + #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE) +#endif +#ifndef INCLUDE_xEventGroupSetBitFromISR + #define INCLUDE_xEventGroupSetBitFromISR 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 /* 1: use application specific vApplicationDaemonTaskStartupHook(), 0: do not use hook */ +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#define configUSE_TASK_FPU_SUPPORT 1 + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ +#define INCLUDE_vTaskEndScheduler 0 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_pcTaskGetTaskName 1 +/* -------------------------------------------------------------------- */ +#define INCLUDE_pxTaskGetStackStart (1 && configUSE_SEGGER_SYSTEM_VIEWER_HOOKS) +/* -------------------------------------------------------------------- */ +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* Cortex-M specific definitions. */ + #if configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define configPRIO_BITS 4 /* 4 bits/16 priority levels on ARM Cortex M4 (Kinetis K Family) */ + #else + #define configPRIO_BITS 2 /* 2 bits/4 priority levels on ARM Cortex M0+ (Kinetis L Family) */ + #endif + + /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ + #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + + /* The highest interrupt priority that can be used by any interrupt service + routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + PRIORITY THAN THIS! (higher priorities are lower numeric values on an ARM Cortex-M). */ + #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + + /* Interrupt priorities used by the kernel port layer itself. These are generic + to all Cortex-M ports, and do not rely on any particular library functions. */ + #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) + + /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ + #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configKERNEL_INTERRUPT_PRIORITY (7) +#endif + +/* Normal assert() semantics without relying on the provision of an assert.h header file. */ +#define configASSERT(x) if((x)==0) { taskDISABLE_INTERRUPTS(); for( ;; ); } +#if 0 /* version for RISC-V with a debug break: */ +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); } +#endif + +/* RISC-V only: If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. + Otherwise set configCLINT_BASE_ADDRESS to 0. + */ +#define configCLINT_BASE_ADDRESS 0x0 + +/*---------------------------------------------------------------------------------------*/ +/* MPU and TrustZone settings */ +#ifndef configENABLE_FPU + #define configENABLE_FPU (0) +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0) +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0) +#endif /* configENABLE_TRUSTZONE */ +/*---------------------------------------------------------------------------------------*/ + +/* custom include file: */ +// #include "CustomFreeRTOSSettings.h + + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS_license.txt b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS_license.txt new file mode 100644 index 0000000..a4aa909 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/FreeRTOS_license.txt @@ -0,0 +1,38 @@ +The FreeRTOS kernel is released under the MIT open source license, the text of +which is provided below. + +This license covers the FreeRTOS kernel source files, which are located in the +/FreeRTOS/Source directory of the official FreeRTOS kernel download. It also +covers most of the source files in the demo application projects, which are +located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The +demo projects may also include third party software that is not part of FreeRTOS +and is licensed separately to FreeRTOS. Examples of third party software +includes header files provided by chip or tools vendors, linker scripts, +peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS +directory is either open source or distributed with permission, and is free for +use. For the avoidance of doubt, refer to the comments at the top of each +source file. + + +License text: +------------- + +Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +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. + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.c new file mode 100644 index 0000000..bca7480 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.c @@ -0,0 +1,242 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HF1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : HardFault +** Version : Component 01.022, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Component to simplify hard faults for ARM (Kinetis, S32K). +** Settings : +** Component name : HF1 +** Contents : +** HardFaultHandler - void HF1_HardFaultHandler(void); +** Deinit - void HF1_Deinit(void); +** Init - void HF1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file HF1.h +** @version 01.00 +** @brief +** Component to simplify hard faults for ARM (Kinetis, S32K). +*/ +/*! +** @addtogroup HF1_module HF1 module documentation +** @{ +*/ + +/* MODULE HF1. */ + +#include "HF1.h" + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +/* +** =================================================================== +** Method : HF1_HandlerC (component HardFault) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/** + * This is called from the HardFaultHandler with a pointer the Fault stack + * as the parameter. We can then read the values from the stack and place them + * into local variables for ease of reading. + * We then read the various Fault Status and Address Registers to help decode + * cause of the fault. + * The function ends with a BKPT instruction to force control back into the debugger + */ +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +void HF1_HandlerC(uint32_t *hardfault_args) +{ + /*lint -save -e550 Symbol not accessed. */ + static volatile unsigned long stacked_r0; + static volatile unsigned long stacked_r1; + static volatile unsigned long stacked_r2; + static volatile unsigned long stacked_r3; + static volatile unsigned long stacked_r12; + static volatile unsigned long stacked_lr; + static volatile unsigned long stacked_pc; + static volatile unsigned long stacked_psr; + static volatile unsigned long _CFSR; + static volatile unsigned long _HFSR; + static volatile unsigned long _DFSR; + static volatile unsigned long _AFSR; + static volatile unsigned long _BFAR; + static volatile unsigned long _MMAR; + stacked_r0 = ((unsigned long)hardfault_args[0]); // http://www.asciiworld.com/-Smiley,20-.html + stacked_r1 = ((unsigned long)hardfault_args[1]); // oooo$$$$$$$$$$$$oooo + stacked_r2 = ((unsigned long)hardfault_args[2]); // oo$$$$$$$$$$$$$$$$$$$$$$$$o + stacked_r3 = ((unsigned long)hardfault_args[3]); // oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o o$ $$ o$ + stacked_r12 = ((unsigned long)hardfault_args[4]); // o $ oo o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o $$ $$ $$o$ + stacked_lr = ((unsigned long)hardfault_args[5]); // oo $ $ "$ o$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$o $$$o$$o$ + stacked_pc = ((unsigned long)hardfault_args[6]); // "$$$$$$o$ o$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$o $$$$$$$$ + stacked_psr = ((unsigned long)hardfault_args[7]); // $$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$ + // $$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$$$$$$ """$$$ + /* Configurable Fault Status Register */ // "$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$ + /* Consists of MMSR, BFSR and UFSR */ // $$$ o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$o + _CFSR = (*((volatile unsigned long *)(0xE000ED28))); // o$$" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$o + // $$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o + /* Hard Fault Status Register */ // o$$$oooo$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ o$$$$$$$$$$$$$$$$$ + _HFSR = (*((volatile unsigned long *)(0xE000ED2C))); // $$$$$$$$"$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$"""""""" + // """" $$$$ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" o$$$ + /* Debug Fault Status Register */ // "$$$o """$$$$$$$$$$$$$$$$$$"$$" $$$ + _DFSR = (*((volatile unsigned long *)(0xE000ED30))); // $$$o "$$""$$$$$$"""" o$$$ + // $$$$o o$$$" + /* Auxiliary Fault Status Register */ // "$$$$o o$$$$$$o"$$$$o o$$$$ + _AFSR = (*((volatile unsigned long *)(0xE000ED3C))); // "$$$$$oo ""$$$$o$$$$$o o$$$$"" + // ""$$$$$oooo "$$$o$$$$$$$$$""" + // ""$$$$$$$oo $$$$$$$$$$ + /* Read the Fault Address Registers. */ // """"$$$$$$$$$$$ + /* These may not contain valid values. */ // $$$$$$$$$$$$ + /* Check BFARVALID/MMARVALID to see */ // $$$$$$$$$$" + /* if they are valid values */ // "$$$"" + /* MemManage Fault Address Register */ + _MMAR = (*((volatile unsigned long *)(0xE000ED34))); + /* Bus Fault Address Register */ + _BFAR = (*((volatile unsigned long *)(0xE000ED38))); + +#if 0 /* experimental, seems not to work properly with GDB in KDS V3.2.0 */ +#ifdef __GNUC__ /* might improve stack, see https://www.element14.com/community/message/199113/l/gdb-assisted-debugging-of-hard-faults#199113 */ + __asm volatile ( + "tst lr,#4 \n" /* check which stack pointer we are using */ + "ite eq \n" + "mrseq r0, msp \n" /* use MSP */ + "mrsne r0, psp \n" /* use PSP */ + "mov sp, r0 \n" /* set stack pointer so GDB shows proper stack frame */ + ); +#endif +#endif + __asm("BKPT #0\n") ; /* cause the debugger to stop */ + /*lint -restore */ +} + +/* +** =================================================================== +** Method : HardFaultHandler (component HardFault) +** +** Description : +** Hard Fault Handler +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +__attribute__((naked)) +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT +void HardFault_Handler(void) +#else +void HF1_HardFaultHandler(void) +#endif +{ + __asm volatile ( + ".syntax unified \n" /* needed for the 'adds r1,#2' below */ + " movs r0,#4 \n" /* load bit mask into R0 */ + " mov r1, lr \n" /* load link register into R1 */ + " tst r0, r1 \n" /* compare with bitmask */ + " beq _MSP \n" /* if bitmask is set: stack pointer is in PSP. Otherwise in MSP */ + " mrs r0, psp \n" /* otherwise: stack pointer is in PSP */ + " b _GetPC \n" /* go to part which loads the PC */ + "_MSP: \n" /* stack pointer is in MSP register */ + " mrs r0, msp \n" /* load stack pointer into R0 */ + "_GetPC: \n" /* find out where the hard fault happened */ + " ldr r1,[r0,#24] \n" /* load program counter into R1. R1 contains address of the next instruction where the hard fault happened */ +#if HF1_CONFIG_SETTING_SEMIHOSTING + /* The following code checks if the hard fault is caused by a semihosting BKPT instruction which is "BKPT 0xAB" (opcode: 0xBEAB) + The idea is taken from the MCUXpresso IDE/SDK code, so credits and kudos to the MCUXpresso IDE team! */ + " ldrh r2,[r1] \n" /* load opcode causing the fault */ + " ldr r3,=0xBEAB \n" /* load constant 0xBEAB (BKPT 0xAB) into R3" */ + " cmp r2,r3 \n" /* is it the BKPT 0xAB? */ + " beq _SemihostReturn \n" /* if yes, return from semihosting */ + " b HF1_HandlerC \n" /* if no, dump the register values and halt the system */ + "_SemihostReturn: \n" /* returning from semihosting fault */ + " adds r1,#2 \n" /* r1 points to the semihosting BKPT instruction. Adjust the PC to skip it (2 bytes) */ + " str r1,[r0,#24] \n" /* store back the ajusted PC value to the interrupt stack frame */ + " movs r1,#32 \n" /* need to pass back a return value to emulate a sucessful semihosting operation. 32 is an arbitrary value */ + " str r1,[r0,#0] \n" /* store the return value on the stack frame */ + " bx lr \n" /* return from the exception handler back to the application */ +#else + " b HF1_HandlerC \n" /* decode more information. R0 contains pointer to stack frame */ +#endif + ); +} + +/* +** =================================================================== +** Method : Deinit (component HardFault) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void HF1_Deinit(void) +{ +#if HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SCB_ACTLR &= ~(SCB_ACTLR_DISDEFWBUF_MASK); /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */ + #elif MCUC1_CONFIG_NXP_SDK_USED && MCUC1_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */ + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISDEFWBUF_Msk; + #endif +#endif +} + +/* +** =================================================================== +** Method : Init (component HardFault) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void HF1_Init(void) +{ +#if HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SCB_ACTLR |= SCB_ACTLR_DISDEFWBUF_MASK; /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */ + #elif MCUC1_CONFIG_NXP_SDK_USED && MCUC1_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISDEFWBUF_Msk; + #endif +#endif +} + + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* END HF1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.h new file mode 100644 index 0000000..33132ef --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1.h @@ -0,0 +1,123 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HF1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : HardFault +** Version : Component 01.022, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Component to simplify hard faults for ARM (Kinetis, S32K). +** Settings : +** Component name : HF1 +** Contents : +** HardFaultHandler - void HF1_HardFaultHandler(void); +** Deinit - void HF1_Deinit(void); +** Init - void HF1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file HF1.h +** @version 01.00 +** @brief +** Component to simplify hard faults for ARM (Kinetis, S32K). +*/ +/*! +** @addtogroup HF1_module HF1 module documentation +** @{ +*/ + +#ifndef __HF1_H +#define __HF1_H + +/* MODULE HF1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "HF1config.h" /* configuration */ + + + + +void HF1_HardFaultHandler(void); +/* +** =================================================================== +** Method : HardFaultHandler (component HardFault) +** +** Description : +** Hard Fault Handler +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#ifdef __GNUC__ /* 'used' attribute needed for GNU LTO (Link Time Optimization) */ +void HF1_HandlerC(uint32_t *hardfault_args) __attribute__((used)); +#else +void HF1_HandlerC(uint32_t *hardfault_args); +#endif +/* +** =================================================================== +** Method : HF1_HandlerC (component HardFault) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void HF1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component HardFault) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void HF1_Init(void); +/* +** =================================================================== +** Method : Init (component HardFault) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END HF1. */ + +#endif +/* ifndef __HF1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/HF1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1config.h new file mode 100644 index 0000000..267b405 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/HF1config.h @@ -0,0 +1,25 @@ +/** + * \file + * \brief Configuration header file for HardFault + * + * This header file is used to configure settings of the HardFault module. + */ + +#ifndef __HF1_CONFIG_H +#define __HF1_CONFIG_H + +#define HF1_CONFIG_SETTING_HAS_ACTLR (1 || (defined(__CORTEX_M) && __CORTEX_M>=3)) + /*!< 1: Cortex-M3, M4 have Auxiliary Control Register, ACTLR register */ + +#ifndef HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #define HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER (0 && HF1_CONFIG_SETTING_HAS_ACTLR) + /*!< 1: disable write buffer in ACTLR register */ +#endif + +#ifndef HF1_CONFIG_SETTING_SEMIHOSTING + #define HF1_CONFIG_SETTING_SEMIHOSTING (1) + /*!< 1: do not stop in handler with semihosting and no debugger attached. 0: semihosting hardfault will stop target */ +#endif + + +#endif /* __HF1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/IO_Map.h b/Projects/tinyK20_SolderDispenser/Generated_Code/IO_Map.h new file mode 100644 index 0000000..b859493 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/IO_Map.h @@ -0,0 +1,79 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : IO_Map.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : IO_Map +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file IO_Map.h +** @version 01.00 +** @brief +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +*/ +/*! +** @addtogroup IO_Map_module IO_Map module documentation +** @{ +*/ + +#ifndef __IO_Map_H +#define __IO_Map_H + +#include "MK20D5.h" + +#endif +/* __IO_Map_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.c new file mode 100644 index 0000000..7c4f90f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.c @@ -0,0 +1,124 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Inhr1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Inhr1 +** Pin for I/O : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/EWM_OUT_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool Inhr1_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Inhr1.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Inhr1_module Inhr1 module documentation +** @{ +*/ + +/* MODULE Inhr1. */ + +#include "Inhr1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : Inhr1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool Inhr1_GetVal(void) + +** This method is implemented as a macro. See Inhr1.h file. ** +*/ + +/* END Inhr1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.h new file mode 100644 index 0000000..bb3859c --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Inhr1.h @@ -0,0 +1,136 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Inhr1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Inhr1 +** Pin for I/O : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/UART0_COL_b/FTM0_CH5/EWM_OUT_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool Inhr1_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Inhr1.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Inhr1_module Inhr1 module documentation +** @{ +*/ + +#ifndef __Inhr1_H +#define __Inhr1_H + +/* MODULE Inhr1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd9.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : Inhr1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define Inhr1_GetVal() (BitIoLdd9_GetVal(BitIoLdd9_DeviceData)) + +/* END Inhr1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __Inhr1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.c new file mode 100644 index 0000000..52e13c3 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.c @@ -0,0 +1,272 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KEY1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Key +** Version : Component 01.115, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** +** Contents : +** isIdle - bool KEY1_isIdle(void); +** GetKeys - uint8_t KEY1_GetKeys(void); +** ScanKeys - void KEY1_ScanKeys(void); +** +** * Copyright (c) 2014-2018, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KEY1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KEY1_module KEY1 module documentation +** @{ +*/ + +/* MODULE KEY1. */ + +#include "Events.h" +#include "KEY1.h" + +/*! States of the key detection state machine. */ +#define DBC_KEY_IDLE 0 /* DBC_PRESSED -> DBC_WAIT -> DBC_IDLE ; + DBC_PRESSED -> DBC_PRESSED ; + DBC_IDLE -> DBC_IDLE ; +} +\enddot +*/ +/* Internal method prototypes */ +static void Scan(void); + +/* +** =================================================================== +** Method : KEY1_Init (component Key) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void KEY1_Init(void) +{ + DBC_KeyState = DBC_KEY_IDLE; +} + +/* +** =================================================================== +** Method : Scan (component Key) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void Scan(void) +{ + KEY1_KeyStorage keys; + + switch(DBC_KeyState) { + case DBC_KEY_IDLE: /* Idle, and now getting a key */ + DBC_ScanValue = KEY1_GetKeys(); /* a one bit indicates key pressed */ + if (DBC_ScanValue==0) { /* no keys pressed */ + return; + } + #if KEY1_LONG_KEY_DETECTION + DBC_LongKeyCount = 0; + #endif + DBC_KeyState = DBC_KEY_PRESSED; /* advance to next state */ + #if KEY1_ON_KEY_PRESSED_EVENT + // KEY1_ON_KEY_PRESSED_EVENT_HANDLER(DBC_ScanValue); /* send event immediately after press detected */ + #endif + TRG1_AddTrigger(TRG1_KEY1_PRESS, DBC_DEBOUNCE_TIME, Scan); + break; + + case DBC_KEY_PRESSED: + keys = KEY1_GetKeys(); /* a one bit indicates key pressed */ + if (keys == DBC_ScanValue) { /* still pressing the same keys */ + #if KEY1_LONG_KEY_DETECTION + DBC_LongKeyCount++; + if (DBC_LongKeyCount >= DBC_LONG_KEY_ITERATIONS) { /* yes, long key press detected */ + #if KEY1_ON_KEY_RELEASED_LONG_EVENT + KEY1_ON_KEY_PRESSED_LONG_EVENT_HANDLER(DBC_ScanValue); + #endif + DBC_LongKeyCount = DBC_LONG_KEY_ITERATIONS; /* avoid overflow */ + DBC_KeyState = DBC_KEY_WAIT_RELEASE_LONG; /* advance to next state */ + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); + } else { + #if KEY1_ON_KEY_HOLD_EVENT + KEY1_ON_KEY_HOLD_EVENT_HANDLER(DBC_ScanValue); + #endif + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); /* continue waiting */ + } + #else + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); /* continue waiting */ + #endif + #if KEY1_NUMBER_OF_KEYS != 1 + } else if ((DBC_ScanValue|keys)==keys) { /* we have here at least one additional key pressed than before */ + DBC_KeyState = DBC_KEY_IDLE; + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); /* restart debouncing */ + #endif + } else { /* we got same set of key(s): so it was only for a short time */ + #if KEY1_ON_KEY_PRESSED_EVENT + KEY1_ON_KEY_PRESSED_EVENT_HANDLER(DBC_ScanValue); /* send short press event */ + #endif + DBC_KeyState = DBC_KEY_WAIT_RELEASE; /* advance to next state */ + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); + } + break; + + case DBC_KEY_WAIT_RELEASE: + #if KEY1_LONG_KEY_DETECTION + case DBC_KEY_WAIT_RELEASE_LONG: + #endif + /* wait until keys are released */ + keys = KEY1_GetKeys(); /* a one bit indicates key pressed */ + if (keys==0) { /* a zero bit means: key(s) released */ + #if KEY1_LONG_KEY_DETECTION + if (DBC_KeyState == DBC_KEY_WAIT_RELEASE_LONG) { + #if KEY1_ON_KEY_RELEASED_LONG_EVENT + KEY1_ON_KEY_RELEASED_LONG_EVENT_HANDLER(DBC_ScanValue); + #endif + #if KEY1_ON_KEY_RELEASED_EVENT + } else { + KEY1_ON_KEY_RELEASED_EVENT_HANDLER(DBC_ScanValue); + #endif + } + #elif KEY1_ON_KEY_RELEASED_EVENT + KEY1_ON_KEY_RELEASED_EVENT_HANDLER(DBC_ScanValue); + #endif + /* All keys released, go back to idle state. */ + DBC_KeyState = DBC_KEY_IDLE; /* go back to idle */ + #if KEY1_NUMBER_OF_KEYS != 1 + } else if (DBC_ScanValue != keys && (DBC_ScanValue|keys)==keys) { /* we have here at least one additional key pressed than before */ + DBC_KeyState = DBC_KEY_IDLE; + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); /* restart debouncing */ + #endif + } else { /* continue waiting */ + TRG1_AddTrigger(TRG1_KEY1_PRESS, 1, Scan); + } + break; + } +} + +/* +** =================================================================== +** Method : isIdle (component Key) +** +** Description : +** Determine if the deriver is idle. This is useful to check +** before entering a low power mode. +** Parameters : None +** Returns : +** --- - returns true if the driver is idle. +** =================================================================== +*/ +bool KEY1_isIdle(void) +{ + return (bool)(DBC_KeyState==DBC_KEY_IDLE); +} + +/* +** =================================================================== +** Method : GetKeys (component Key) +** +** Description : +** Returns the port value of the keys. A one in the returned +** value indicates a key pressed. +** Parameters : None +** Returns : +** --- - key status +** =================================================================== +*/ +/* +uint8_t KEY1_GetKeys(void) +{ + method is implemented as a macro in the header file KEY1.h +} +*/ + +/* +** =================================================================== +** Method : ScanKeys (component Key) +** +** Description : +** Scans/Polls the keys +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KEY1_ScanKeys(void) +{ + if (DBC_KeyState==DBC_KEY_IDLE) { /* we are not already debouncing/scanning a key */ + Scan(); + } +} + +/* END KEY1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.h new file mode 100644 index 0000000..82a051b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/KEY1.h @@ -0,0 +1,154 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KEY1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Key +** Version : Component 01.115, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** +** Contents : +** isIdle - bool KEY1_isIdle(void); +** GetKeys - uint8_t KEY1_GetKeys(void); +** ScanKeys - void KEY1_ScanKeys(void); +** +** * Copyright (c) 2014-2018, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KEY1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KEY1_module KEY1 module documentation +** @{ +*/ + +#ifndef __KEY1_H +#define __KEY1_H + +/* MODULE KEY1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "CS1.h" +#include "Inhr1.h" +#include "TRG1.h" + +#include "Cpu.h" + +#define KEY1_NUMBER_OF_KEYS 1 /* 1: generate key release event, 0: no key release event */ +#define KEY1_KEYS_MASK (0xFFu>>(8-KEY1_NUMBER_OF_KEYS)) /* /* uint8_t, int16_t, ... */ + #include /* bool, true, false, ... */ + #endif + + /* boolean values */ + #ifndef FALSE + #define FALSE 0x00u + #endif + #ifndef TRUE + #define TRUE 0x01u + #endif + + /* error codes */ + #define ERR_OK 0x00U /*!< OK */ + #define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ + #define ERR_RANGE 0x02U /*!< Parameter out of range. */ + #define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ + #define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ + #define ERR_MATH 0x05U /*!< Overflow during evaluation. */ + #define ERR_ENABLED 0x06U /*!< Device is enabled. */ + #define ERR_DISABLED 0x07U /*!< Device is disabled. */ + #define ERR_BUSY 0x08U /*!< Device is busy. */ + #define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ + #define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ + #define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ + #define ERR_BUSOFF 0x0CU /*!< Bus not available. */ + #define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ + #define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ + #define ERR_PARITY 0x0FU /*!< Parity error is detected. */ + #define ERR_NOISE 0x10U /*!< Noise error is detected. */ + #define ERR_IDLE 0x11U /*!< Idle error is detected. */ + #define ERR_FAULT 0x12U /*!< Fault error is detected. */ + #define ERR_BREAK 0x13U /*!< Break char is received during communication. */ + #define ERR_CRC 0x14U /*!< CRC error is detected. */ + #define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ + #define ERR_PROTECT 0x16U /*!< Protection error is detected. */ + #define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ + #define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ + #define ERR_COMMON 0x19U /*!< Common error of a device. */ + #define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ + #define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ + #define ERR_QFULL 0x1CU /*!< Queue is full. */ + #define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ + #define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ + #define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ + #define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ + #define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ + #define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ + #define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ + #define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ + #define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ + #define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ + #define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ + #define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ + #define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ + #define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ + #define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ + #define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ + #define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ + #define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ + #define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ + #define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ + #define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ + #define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ + #define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ + #define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ + #define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + + /* Other basic data types */ + typedef signed char int8; + typedef signed short int int16; + typedef signed long int int32; + + typedef unsigned char uint8; + typedef unsigned short int uint16; + typedef unsigned long int uint32; +#endif + + + + + +void MCUC1_Init(void); +/* +** =================================================================== +** Method : Init (component McuLibConfig) +** +** Description : +** Driver initialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void MCUC1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component McuLibConfig) +** +** Description : +** Driver deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END MCUC1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MCUC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MCUC1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/MCUC1config.h new file mode 100644 index 0000000..cbb0957 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MCUC1config.h @@ -0,0 +1,162 @@ +/** + * \file + * \brief Configuration header file for McuLibConfig + * + * This header file is used to configure settings of the McuLibConfig module. + */ + +#ifndef __MCUC1_CONFIG_H +#define __MCUC1_CONFIG_H + +/* identification of CPU/core used. __CORTEX_M is defined in CMSIS-Core. + Otherwise CPU Family is set automatically by Processor Expert: detected: Kinetis (supported: "Kinetis", "S32K", "HCS08") +*/ +#ifndef MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M (1 || defined(__CORTEX_M)) + /*!< 1: ARM Cortex-M family, 0 otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_KINETIS + #define MCUC1_CONFIG_CPU_IS_KINETIS (1 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP Kinetis CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_S32K + #define MCUC1_CONFIG_CPU_IS_S32K (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP S32K CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC + #define MCUC1_CONFIG_CPU_IS_LPC (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP LPC CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC55xx + #define MCUC1_CONFIG_CPU_IS_LP55Cxx (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CPU_IS_LPC) + /*!< 1: NXP LPC55xx CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_CPU_IS_STM32 (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: STM32 ARM Cortex CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_IMXRT + #define MCUC1_CONFIG_CPU_IS_IMXRT (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP i.Mx RT CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_NORDIC_NRF + #define MCUC1_CONFIG_CPU_IS_NORDIC_NRF (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: Nordic nRF, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_HCS08 + #define MCUC1_CONFIG_CPU_IS_HCS08 (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: HCS08 CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V + #define MCUC1_CONFIG_CPU_IS_RISC_V (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: RISC-V CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY + #define MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY (1 && MCUC1_CONFIG_CPU_IS_RISC_V) + /*!< 1: VEGA Board: RISC-V RV32M1 RI5CY, 0: other core */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_ESP32 + #ifndef __XTENSA__ + #define __XTENSA__ 0 + #endif + #define MCUC1_CONFIG_CPU_IS_ESP32 (__XTENSA__) + /*!< 1: ESP32 CPU family, 0: otherwise. The ESP32 compiler defines __XTENSA__ with a value of 1 */ +#endif + + +/* identification of Cortex-M core. __FPU_USED can be defined in CMSIS-Core */ +#ifndef MCUC1_CONFIG_CORTEX_M + #define MCUC1_CONFIG_CORTEX_M (4) + /*!< 0: Cortex-M0, 3: M3, 4: M4, 7: M7, 33: M33, -1 otherwise */ +#endif +#if (0 && !defined(MCUC1_CONFIG_FPU_PRESENT) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_PRESENT) && (__FPU_PRESENT==1)) /* __FPU_PRESENT can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_PRESENT (1) +#else + #define MCUC1_CONFIG_FPU_PRESENT (0) +#endif + /*!< 1: floating point unit present, 0: otherwise */ +#if (0 && !defined(MCUC1_CONFIG_FPU_USED) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_USED) && (__FPU_USED==1)) /* __FPU_USED can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_USED (1) +#else + #define MCUC1_CONFIG_FPU_USED (0) +#endif + /*!< 1: using floating point unit, 0: otherwise */ + +/* macro for little and big endianess. ARM is little endian */ +#define MCUC1_CONFIG_CPU_IS_LITTLE_ENDIAN (MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + +/* Identifiers used to identify the SDK */ +#define MCUC1_CONFIG_SDK_GENERIC 0 + /*!< using a generic API/SDK */ +#define MCUC1_CONFIG_SDK_PROCESSOR_EXPERT 1 + /*!< using Processor Expert SDK */ +#define MCUC1_CONFIG_SDK_KINETIS_1_3 2 + /*!< using NXP Kinetis SDK V1.3 */ +#define MCUC1_CONFIG_SDK_KINETIS_2_0 3 + /*!< using NXP Kinetis SDK V2.0 */ +#define MCUC1_CONFIG_SDK_MCUXPRESSO_2_0 4 + /*!< using NXP MCUXpresso SDK V2.x, same as Kinetis SDK v2.0 */ +#define MCUC1_CONFIG_SDK_S32K 5 + /*!< SDK for S32K */ +#define MCUC1_CONFIG_SDK_NORDIC_NRF5 6 + /*!< Nordic nRF5 SDK */ + +#ifndef MCUC1_CONFIG_SDK_VERSION_MAJOR + #define MCUC1_CONFIG_SDK_VERSION_MAJOR (2) + /*!< SDK major version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_MINOR + #define MCUC1_CONFIG_SDK_VERSION_MINOR (5) + /*!< SDK minor version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_BUILD + #define MCUC1_CONFIG_SDK_VERSION_BUILD (0) + /*!< SDK build version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION + #define MCUC1_CONFIG_SDK_VERSION (MCUC1_CONFIG_SDK_VERSION_MAJOR*100)+(MCUC1_CONFIG_SDK_VERSION_MINOR*10)+MCUC1_CONFIG_SDK_VERSION_BUILD + /*!< Builds a single number with the SDK version (major, minor, build), e.g. 250 for 2.5.0 */ +#endif + +/* specify the SDK and API used */ +#ifndef MCUC1_CONFIG_SDK_VERSION_USED +#if MCUC1_CONFIG_CPU_IS_ESP32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For ESP32 we are using a generic SDK (actually the IDF one) */ +#elif MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For STM32 we are using a generic SDK (actually the CubeMX one) */ +#else + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + /*!< identify the version of SDK/API used */ +#endif +#endif + + +/* Configuration macro if FreeRTOS is used */ +#ifndef MCUC1_CONFIG_SDK_USE_FREERTOS + #define MCUC1_CONFIG_SDK_USE_FREERTOS (1) + /*!< 1: Use FreeRTOS; 0: no FreeRTOS used */ +#endif + +/* special macro to identify a set of SDKs used */ +#define MCUC1_CONFIG_NXP_SDK_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K) \ + ) + /*!< Using one of the Freescale/NXP SDKs */ + +#define MCUC1_CONFIG_NXP_SDK_2_0_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + ) + /*!< Using Freescale/NXP SDK V2.0 */ + +#define MCUC1_CONFIG_PEX_SDK_USED (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_PROCESSOR_EXPERT) + /*!< Using Processor Expert API */ + +#endif /* __MCUC1_CONFIG_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.c new file mode 100644 index 0000000..ce3e307 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MS1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MS1 +** Pin for I/O : PTD3/SPI0_SIN/UART2_TX +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MS1_GetVal(void); +** PutVal - void MS1_PutVal(bool Val); +** ClrVal - void MS1_ClrVal(void); +** SetVal - void MS1_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MS1.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MS1_module MS1 module documentation +** @{ +*/ + +/* MODULE MS1. */ + +#include "MS1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : MS1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool MS1_GetVal(void) + +** This method is implemented as a macro. See MS1.h file. ** +*/ + +/* +** =================================================================== +** Method : MS1_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void MS1_PutVal(bool Val) + +** This method is implemented as a macro. See MS1.h file. ** +*/ + +/* +** =================================================================== +** Method : MS1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MS1_ClrVal(void) + +** This method is implemented as a macro. See MS1.h file. ** +*/ + +/* +** =================================================================== +** Method : MS1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MS1_SetVal(void) + +** This method is implemented as a macro. See MS1.h file. ** +*/ + +/* END MS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.h new file mode 100644 index 0000000..a75b03b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MS1.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MS1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MS1 +** Pin for I/O : PTD3/SPI0_SIN/UART2_TX +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MS1_GetVal(void); +** PutVal - void MS1_PutVal(bool Val); +** ClrVal - void MS1_ClrVal(void); +** SetVal - void MS1_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MS1.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MS1_module MS1 module documentation +** @{ +*/ + +#ifndef __MS1_H +#define __MS1_H + +/* MODULE MS1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd6.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : MS1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define MS1_GetVal() (BitIoLdd6_GetVal(BitIoLdd6_DeviceData)) + +/* +** =================================================================== +** Method : MS1_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define MS1_PutVal(Val) (BitIoLdd6_PutVal(BitIoLdd6_DeviceData, (Val))) + +/* +** =================================================================== +** Method : MS1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MS1_ClrVal() (BitIoLdd6_ClrVal(BitIoLdd6_DeviceData)) + +/* +** =================================================================== +** Method : MS1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MS1_SetVal() (BitIoLdd6_SetVal(BitIoLdd6_DeviceData)) + +/* END MS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MS1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.c b/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.c new file mode 100644 index 0000000..06ecd09 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MS2.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MS2 +** Pin for I/O : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MS2_GetVal(void); +** PutVal - void MS2_PutVal(bool Val); +** ClrVal - void MS2_ClrVal(void); +** SetVal - void MS2_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MS2.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MS2_module MS2 module documentation +** @{ +*/ + +/* MODULE MS2. */ + +#include "MS2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : MS2_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool MS2_GetVal(void) + +** This method is implemented as a macro. See MS2.h file. ** +*/ + +/* +** =================================================================== +** Method : MS2_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void MS2_PutVal(bool Val) + +** This method is implemented as a macro. See MS2.h file. ** +*/ + +/* +** =================================================================== +** Method : MS2_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MS2_ClrVal(void) + +** This method is implemented as a macro. See MS2.h file. ** +*/ + +/* +** =================================================================== +** Method : MS2_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MS2_SetVal(void) + +** This method is implemented as a macro. See MS2.h file. ** +*/ + +/* END MS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.h b/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.h new file mode 100644 index 0000000..7d1a20f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MS2.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MS2.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MS2 +** Pin for I/O : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MS2_GetVal(void); +** PutVal - void MS2_PutVal(bool Val); +** ClrVal - void MS2_ClrVal(void); +** SetVal - void MS2_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MS2.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MS2_module MS2 module documentation +** @{ +*/ + +#ifndef __MS2_H +#define __MS2_H + +/* MODULE MS2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd5.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : MS2_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define MS2_GetVal() (BitIoLdd5_GetVal(BitIoLdd5_DeviceData)) + +/* +** =================================================================== +** Method : MS2_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define MS2_PutVal(Val) (BitIoLdd5_PutVal(BitIoLdd5_DeviceData, (Val))) + +/* +** =================================================================== +** Method : MS2_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MS2_ClrVal() (BitIoLdd5_ClrVal(BitIoLdd5_DeviceData)) + +/* +** =================================================================== +** Method : MS2_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MS2_SetVal() (BitIoLdd5_SetVal(BitIoLdd5_DeviceData)) + +/* END MS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MS2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.c b/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.c new file mode 100644 index 0000000..fa8f661 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MotEn.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MotEn +** Pin for I/O : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MotEn_GetVal(void); +** PutVal - void MotEn_PutVal(bool Val); +** ClrVal - void MotEn_ClrVal(void); +** SetVal - void MotEn_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MotEn.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MotEn_module MotEn module documentation +** @{ +*/ + +/* MODULE MotEn. */ + +#include "MotEn.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : MotEn_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool MotEn_GetVal(void) + +** This method is implemented as a macro. See MotEn.h file. ** +*/ + +/* +** =================================================================== +** Method : MotEn_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void MotEn_PutVal(bool Val) + +** This method is implemented as a macro. See MotEn.h file. ** +*/ + +/* +** =================================================================== +** Method : MotEn_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MotEn_ClrVal(void) + +** This method is implemented as a macro. See MotEn.h file. ** +*/ + +/* +** =================================================================== +** Method : MotEn_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MotEn_SetVal(void) + +** This method is implemented as a macro. See MotEn.h file. ** +*/ + +/* END MotEn. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.h b/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.h new file mode 100644 index 0000000..d4acc6a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MotEn.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MotEn.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MotEn +** Pin for I/O : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MotEn_GetVal(void); +** PutVal - void MotEn_PutVal(bool Val); +** ClrVal - void MotEn_ClrVal(void); +** SetVal - void MotEn_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MotEn.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MotEn_module MotEn module documentation +** @{ +*/ + +#ifndef __MotEn_H +#define __MotEn_H + +/* MODULE MotEn. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd7.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : MotEn_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define MotEn_GetVal() (BitIoLdd7_GetVal(BitIoLdd7_DeviceData)) + +/* +** =================================================================== +** Method : MotEn_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define MotEn_PutVal(Val) (BitIoLdd7_PutVal(BitIoLdd7_DeviceData, (Val))) + +/* +** =================================================================== +** Method : MotEn_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MotEn_ClrVal() (BitIoLdd7_ClrVal(BitIoLdd7_DeviceData)) + +/* +** =================================================================== +** Method : MotEn_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MotEn_SetVal() (BitIoLdd7_SetVal(BitIoLdd7_DeviceData)) + +/* END MotEn. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MotEn_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.c b/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.c new file mode 100644 index 0000000..b890841 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MotSleep.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MotSleep +** Pin for I/O : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MotSleep_GetVal(void); +** PutVal - void MotSleep_PutVal(bool Val); +** ClrVal - void MotSleep_ClrVal(void); +** SetVal - void MotSleep_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MotSleep.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MotSleep_module MotSleep module documentation +** @{ +*/ + +/* MODULE MotSleep. */ + +#include "MotSleep.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : MotSleep_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool MotSleep_GetVal(void) + +** This method is implemented as a macro. See MotSleep.h file. ** +*/ + +/* +** =================================================================== +** Method : MotSleep_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void MotSleep_PutVal(bool Val) + +** This method is implemented as a macro. See MotSleep.h file. ** +*/ + +/* +** =================================================================== +** Method : MotSleep_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MotSleep_ClrVal(void) + +** This method is implemented as a macro. See MotSleep.h file. ** +*/ + +/* +** =================================================================== +** Method : MotSleep_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void MotSleep_SetVal(void) + +** This method is implemented as a macro. See MotSleep.h file. ** +*/ + +/* END MotSleep. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.h b/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.h new file mode 100644 index 0000000..3a20bf5 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/MotSleep.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MotSleep.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 14:09, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : MotSleep +** Pin for I/O : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool MotSleep_GetVal(void); +** PutVal - void MotSleep_PutVal(bool Val); +** ClrVal - void MotSleep_ClrVal(void); +** SetVal - void MotSleep_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file MotSleep.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup MotSleep_module MotSleep module documentation +** @{ +*/ + +#ifndef __MotSleep_H +#define __MotSleep_H + +/* MODULE MotSleep. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd8.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : MotSleep_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define MotSleep_GetVal() (BitIoLdd8_GetVal(BitIoLdd8_DeviceData)) + +/* +** =================================================================== +** Method : MotSleep_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define MotSleep_PutVal(Val) (BitIoLdd8_PutVal(BitIoLdd8_DeviceData, (Val))) + +/* +** =================================================================== +** Method : MotSleep_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MotSleep_ClrVal() (BitIoLdd8_ClrVal(BitIoLdd8_DeviceData)) + +/* +** =================================================================== +** Method : MotSleep_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define MotSleep_SetVal() (BitIoLdd8_SetVal(BitIoLdd8_DeviceData)) + +/* END MotSleep. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MotSleep_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Const.h b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Const.h new file mode 100644 index 0000000..440d241 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Const.h @@ -0,0 +1,95 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Const.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : PE_Const +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "PE_Const" contains internal definitions +** of the constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Const.h +** @version 01.00 +** @brief +** This component "PE_Const" contains internal definitions +** of the constants. +*/ +/*! +** @addtogroup PE_Const_module PE_Const module documentation +** @{ +*/ + +#ifndef __PE_Const_H +#define __PE_Const_H + + +/* Reset cause constants */ +#define RSTSRC_WAKEUP 0x01U /*!< LLWU module wakeup reset */ +#define RSTSRC_LVD 0x02U /*!< Low-voltage detect reset */ +#define RSTSRC_LOC 0x04U /*!< Loss-of-clock reset */ +#define RSTSRC_LOL 0x08U /*!< Loss-of-lock reset */ +#define RSTSRC_COP 0x20U /*!< Watchdog reset */ +#define RSTSRC_WDOG 0x20U /*!< Watchdog reset */ +#define RSTSRC_PIN 0x40U /*!< External pin reset */ +#define RSTSRC_POR 0x80U /*!< Power-on reset */ +#define RSTSRC_JTAG 0x0100U /*!< JTAG reset pin */ +#define RSTSRC_LOCKUP 0x0200U /*!< Core Lock-up reset */ +#define RSTSRC_SW 0x0400U /*!< Software reset */ +#define RSTSRC_MDM_AP 0x0800U /*!< Reset caused by host debugger system */ +#define RSTSRC_EZPT 0x1000U /*!< EzPort reset */ +#define RSTSRC_SACKERR 0x2000U /*!< Stop Mode Acknowledge Error Reset */ + + +/* Low voltage interrupt cause constants */ +#define LVDSRC_LVD 0x01U /*!< Low voltage detect */ +#define LVDSRC_LVW 0x02U /*!< Low-voltage warning */ + +#endif /* _PE_Const_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Error.h b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Error.h new file mode 100644 index 0000000..1f75421 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Error.h @@ -0,0 +1,128 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Error.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : PE_Error +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "PE_Error" contains internal definitions +** of the error constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Error.h +** @version 01.00 +** @brief +** This component "PE_Error" contains internal definitions +** of the error constants. +*/ +/*! +** @addtogroup PE_Error_module PE_Error module documentation +** @{ +*/ + +#ifndef __PE_Error_H +#define __PE_Error_H + +#define ERR_OK 0x00U /*!< OK */ +#define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ +#define ERR_RANGE 0x02U /*!< Parameter out of range. */ +#define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ +#define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ +#define ERR_MATH 0x05U /*!< Overflow during evaluation. */ +#define ERR_ENABLED 0x06U /*!< Device is enabled. */ +#define ERR_DISABLED 0x07U /*!< Device is disabled. */ +#define ERR_BUSY 0x08U /*!< Device is busy. */ +#define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ +#define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ +#define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ +#define ERR_BUSOFF 0x0CU /*!< Bus not available. */ +#define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ +#define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ +#define ERR_PARITY 0x0FU /*!< Parity error is detected. */ +#define ERR_NOISE 0x10U /*!< Noise error is detected. */ +#define ERR_IDLE 0x11U /*!< Idle error is detected. */ +#define ERR_FAULT 0x12U /*!< Fault error is detected. */ +#define ERR_BREAK 0x13U /*!< Break char is received during communication. */ +#define ERR_CRC 0x14U /*!< CRC error is detected. */ +#define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ +#define ERR_PROTECT 0x16U /*!< Protection error is detected. */ +#define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ +#define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ +#define ERR_COMMON 0x19U /*!< Common error of a device. */ +#define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ +#define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ +#define ERR_QFULL 0x1CU /*!< Queue is full. */ +#define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ +#define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ +#define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ +#define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ +#define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ +#define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ +#define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ +#define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ +#define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ +#define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ +#define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ +#define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ +#define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ +#define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ +#define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ +#define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ +#define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ +#define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ +#define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ +#define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ +#define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ +#define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ +#define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ +#define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ +#define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + +#endif /* __PE_Error_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.c b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.c new file mode 100644 index 0000000..f8f51d5 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.c @@ -0,0 +1,194 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ + +/* MODULE PE_LDD. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +/* {FreeRTOS RTOS Adapter} No RTOS driver includes */ + +#include "PE_LDD.h" +#include "Cpu.h" + +/*lint -esym(765,PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory) Disable MISRA rule (8.10) checking for symbols (PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory). */ + +/* +** =========================================================================== +** Array of initialized device structures of LDD components. +** =========================================================================== +*/ +LDD_TDeviceData *PE_LDD_DeviceDataList[10] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; + +/* +** =========================================================================== +** The array of clock frequencies in configured clock configurations. +** =========================================================================== +*/ +/*! The array of clock configurations (frequencies) configured in configured clock configurations of the CPU component. */ +const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER] = { + /* Clock configuration 0 */ + { + CPU_CORE_CLK_HZ_CONFIG_0, /*!< Core clock frequency in clock configuration 0 */ + CPU_BUS_CLK_HZ_CONFIG_0, /*!< Bus clock frequency in clock configuration 0 */ + CPU_FLEXBUS_CLK_HZ_CONFIG_0, /*!< Flexbus clock frequency in clock configuration 0 */ + CPU_FLASH_CLK_HZ_CONFIG_0, /*!< FLASH clock frequency in clock configuration 0 */ + CPU_USB_CLK_HZ_CONFIG_0, /*!< USB clock frequency in clock configuration 0 */ + CPU_PLL_FLL_CLK_HZ_CONFIG_0, /*!< PLL/FLL clock frequency in clock configuration 0 */ + CPU_MCGIR_CLK_HZ_CONFIG_0, /*!< MCG internal reference clock frequency in clock configuration 0 */ + CPU_OSCER_CLK_HZ_CONFIG_0, /*!< System OSC external reference clock frequency in clock configuration 0 */ + CPU_ERCLK32K_CLK_HZ_CONFIG_0, /*!< External reference clock 32k frequency in clock configuration 0 */ + CPU_MCGFF_CLK_HZ_CONFIG_0 /*!< MCG fixed frequency clock */ + } +}; + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK20DX128FT5) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len) +{ + register uint8_t *ptr = (uint8_t*)SourceAddressPtr; + + if (len > 0U) { + while (len--) { + *ptr++ = c; + } + } +} + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK20DX128FT5) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress) +{ + bool result = FALSE; + + switch (PrphBaseAddress) { + /* Base address allocated by peripheral(s) PTD */ + case 0x400FF0C0UL: + /* Base address allocated by peripheral(s) FTM0 */ + case 0x40038000UL: + result = TRUE; + break; + default: + break; + } + return result; +} + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK20DX128FT5) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration) +{ + (void)ClockConfiguration; /*!< Parameter is not used, suppress unused argument warning */ + /* Just one clock configuration defined in CPU component. */ +} + +/* END PE_LDD. */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.h b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.h new file mode 100644 index 0000000..380f0a5 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_LDD.h @@ -0,0 +1,171 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.h +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ +#ifndef __PE_LDD_H +#define __PE_LDD_H + +/* MODULE PE_LDD. */ + +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "MCUC1.h" +#include "WAIT1.h" +#include "RTT1.h" +#include "CLS1.h" +#include "UTIL1.h" +#include "XF1.h" +#include "CS1.h" +#include "Step.h" +#include "BitIoLdd2.h" +#include "Dir.h" +#include "BitIoLdd4.h" +#include "MS2.h" +#include "BitIoLdd5.h" +#include "MS1.h" +#include "BitIoLdd6.h" +#include "MotEn.h" +#include "BitIoLdd7.h" +#include "MotSleep.h" +#include "BitIoLdd8.h" +#include "FRTOS1.h" +#include "USB1.h" +#include "CDC1.h" +#include "Tx1.h" +#include "Rx1.h" +#include "USB0.h" +#include "TMOUT1.h" +#include "HF1.h" +#include "TI1.h" +#include "TimerIntLdd1.h" +#include "TU1.h" +#include "KEY1.h" +#include "Inhr1.h" +#include "BitIoLdd9.h" +#include "TRG1.h" + + +/* +** =================================================================== +** Function prototypes +** =================================================================== +*/ + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK20DX128FT5) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK20DX128FT5) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress); + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK20DX128FT5) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration); + +/* END PE_LDD. */ + + +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Types.h b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Types.h new file mode 100644 index 0000000..295170d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/PE_Types.h @@ -0,0 +1,2543 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Types.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : PE_Types +** Version : Driver 01.01 +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Types.h +** @version 01.01 +** @brief +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +*/ +/*! +** @addtogroup PE_Types_module PE_Types module documentation +** @{ +*/ + +#ifndef __PE_Types_H +#define __PE_Types_H + +/* Standard ANSI C types */ +#include + +#ifndef FALSE + #define FALSE 0x00u /* Boolean value FALSE. FALSE is defined always as a zero value. */ +#endif +#ifndef TRUE + #define TRUE 0x01u /* Boolean value TRUE. TRUE is defined always as a non zero value. */ +#endif + +#ifndef NULL + #define NULL 0x00u +#endif + +/* PE types definition */ +#ifndef __cplusplus + #ifndef bool +typedef unsigned char bool; + #endif +#endif +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; +typedef unsigned long long dlong; +typedef unsigned char TPE_ErrCode; +#ifndef TPE_Float +typedef float TPE_Float; +#endif +#ifndef char_t +typedef char char_t; +#endif + +/* Other basic data types */ +typedef signed char int8; +typedef signed short int int16; +typedef signed long int int32; + +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned long int uint32; + + +/**********************************************************/ +/* Uniform multiplatform 8-bits peripheral access macros */ +/**********************************************************/ + +/* Enable maskable interrupts */ +#define __EI()\ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm("CPSIE f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + +/* Disable maskable interrupts */ +#define __DI() \ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm ("CPSID f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + + + +/* Save status register and disable interrupts */ +#define EnterCritical() \ + do {\ + uint8_t SR_reg_local;\ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "MRS R0, FAULTMASK\n\t" \ + "CPSID f\n\t" \ + "STRB R0, %[output]" \ + : [output] "=m" (SR_reg_local)\ + :: "r0");\ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + if (++SR_lock == 1u) {\ + SR_reg = SR_reg_local;\ + }\ + } while(0) + + +/* Restore status register */ +#define ExitCritical() \ + do {\ + if (--SR_lock == 0u) { \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "ldrb r0, %[input]\n\t"\ + "msr FAULTMASK,r0;\n\t" \ + ::[input] "m" (SR_reg) \ + : "r0"); \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + }\ + } while(0) + + +#define PE_DEBUGHALT() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "BKPT 255") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_NOP() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "NOP") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_WFI() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm("WFI") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + + +/* Interrupt definition template */ +#if !defined(PE_ISR) + #define PE_ISR(ISR_name) void __attribute__ ((interrupt)) ISR_name(void) +#endif + +/* Logical Device Drivers (LDD) types */ + +/*! Logical Device Driver API version */ +#define PE_LDD_VERSION 0x0100U + +/* LDD driver states */ +#define PE_LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION 0x01U /*!< LDD driver is disabled in the selected clock configuration */ +#define PE_LDD_DRIVER_DISABLED_BY_USER 0x02U /*!< LDD driver is disabled by the user */ +#define PE_LDD_DRIVER_BUSY 0x04U /*!< LDD driver is busy */ + +/*! Macro to register component device structure */ +#define PE_LDD_RegisterDeviceStructure(ComponentIndex, DeviceStructure) (PE_LDD_DeviceDataList[ComponentIndex] = DeviceStructure) + +/*! Macro to unregister component device structure */ +#define PE_LDD_UnregisterDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex] = NULL) + +/*! Macro to get the component device structure */ +#define PE_LDD_GetDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex]) + +/* +** =========================================================================== +** LDD component ID specifying the component instance in the project. This ID +** is used internally as an index to the array of LDD device structures. +** =========================================================================== +*/ +#define PE_LDD_COMPONENT_BitIoLdd1_ID 0x00U +#define PE_LDD_COMPONENT_BitIoLdd2_ID 0x01U +#define PE_LDD_COMPONENT_BitIoLdd4_ID 0x02U +#define PE_LDD_COMPONENT_BitIoLdd5_ID 0x03U +#define PE_LDD_COMPONENT_BitIoLdd6_ID 0x04U +#define PE_LDD_COMPONENT_BitIoLdd7_ID 0x05U +#define PE_LDD_COMPONENT_BitIoLdd8_ID 0x06U +#define PE_LDD_COMPONENT_TU1_ID 0x07U +#define PE_LDD_COMPONENT_TimerIntLdd1_ID 0x08U +#define PE_LDD_COMPONENT_BitIoLdd9_ID 0x09U + +/* +** =================================================================== +** Global HAL types and constants +** =================================================================== +*/ +typedef uint32_t LDD_TPinMask; /*!< Pin mask type. */ +typedef uint16_t LDD_TError; /*!< Error type. */ +typedef uint32_t LDD_TEventMask; /*!< Event mask type. */ +typedef uint8_t LDD_TClockConfiguration; /*!< CPU clock configuration type. */ +typedef void LDD_TDeviceData; /*!< Pointer to private device structure managed and used by HAL components. */ +typedef void* LDD_TDeviceDataPtr; /*!< Obsolete type for backward compatibility. */ +typedef void LDD_TData; /*!< General pointer to data. */ +typedef void LDD_TUserData; /*!< Pointer to this type specifies the user or RTOS specific data will be passed as an event or callback parameter. */ + +/*! Driver operation mode type. */ +typedef enum { + DOM_NONE, + DOM_RUN, + DOM_WAIT, + DOM_SLEEP, + DOM_STOP +} LDD_TDriverOperationMode; + +typedef uint16_t LDD_TDriverState; /*!< Driver state type. */ +typedef void LDD_TCallbackParam; /*!< Pointer to this type specifies the user data to be passed as a callback parameter. */ +typedef void (* LDD_TCallback)(LDD_TCallbackParam *CallbackParam); /*!< Callback type used for definition of callback functions. */ + +extern LDD_TDeviceData *PE_LDD_DeviceDataList[]; /*!< Array of LDD component device structures */ + + +/* Fills a memory area block by a specified value. Function defined in PE_LDD.c */ +extern void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + + +/* +** =================================================================== +** RTOS specific types and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} RTOS specific definition of type of Ioctl() command constants */ + + +/* +** =================================================================== +** Published RTOS settings and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} No published RTOS settings */ + + +/* +** =================================================================== +** TimerUnit device types and constants +** =================================================================== +*/ +#define LDD_TIMERUNIT_ON_CHANNEL_0 0x01u /*!< OnChannel0 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_1 0x02u /*!< OnChannel1 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_2 0x04u /*!< OnChannel2 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_3 0x08u /*!< OnChannel3 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_4 0x10u /*!< OnChannel4 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_5 0x20u /*!< OnChannel5 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_6 0x40u /*!< OnChannel6 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_7 0x80u /*!< OnChannel7 event mask value */ +#define LDD_TIMERUNIT_ON_COUNTER_RESTART 0x0100u /*!< OnCounterRestart event mask value */ + +/*! Direction of counting */ +typedef enum { + DIR_UP, /*!< UP */ + DIR_DOWN /*!< DOWN */ +} LDD_TimerUnit_TCounterDirection; + +/*! Output action type (flip-flop action on overrun or compare match) */ +typedef enum { + OUTPUT_NONE, /*!< NONE */ + OUTPUT_TOGGLE, /*!< TOGGLE */ + OUTPUT_CLEAR, /*!< CLEAR */ + OUTPUT_SET /*!< SET */ +} LDD_TimerUnit_TOutAction; + +/*! Input edge type */ +typedef enum { + EDGE_NONE, /*!< NONE */ + EDGE_RISING, /*!< RISING */ + EDGE_FALLING, /*!< FALLING */ + EDGE_BOTH /*!< BOTH */ +} LDD_TimerUnit_TEdge; + +typedef float LDD_TimerUnit_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** CMT device types and constants +** =================================================================== +*/ +#define LDD_CMT_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** PPG device types and constants +** =================================================================== +*/ +#define LDD_PPG_ON_END 0x01u /*!< OnEnd event mask value */ + +typedef float LDD_PPG_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** PWM types and constants +** =================================================================== +*/ +#define LDD_PWM_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** Capture types and constants +** =================================================================== +*/ +#define LDD_CAPTURE_ON_CAPTURE 0x01u /*!< OnCapture event mask value */ +#define LDD_CAPTURE_ON_OVERRUN 0x02u /*!< OnOverrun event mask value */ + +/* +** =================================================================== +** TimerInt types and constants +** =================================================================== +*/ +#define LDD_TIMERINT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** TimerOut types and constants +** =================================================================== +*/ +#define LDD_TIMEROUT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** EventCntr types and constants +** =================================================================== +*/ +#define LDD_EVENTCNTR_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** FreeCntr types and constants +** =================================================================== +*/ +#define LDD_FREECNTR_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** RealTime types and constants +** =================================================================== +*/ + +typedef float LDD_RealTime_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** TimeDate types and constants +** =================================================================== +*/ +#define LDD_TIMEDATE_ON_ALARM 0x01u /*!< OnAlarm event mask value */ +#define LDD_TIMEDATE_ON_SECOND 0x02u /*!< OnSecond event mask value */ + +/*!< Time struct */ +typedef struct { + uint16_t Hour; /*!< Hours (0 - 23) */ + uint16_t Min; /*!< Minutes (0 - 59) */ + uint16_t Sec; /*!< Seconds (0 - 59) */ + uint16_t Sec100; /*!< Hundredths of seconds (0 - 99) */ +} LDD_TimeDate_TTimeRec; + +/*!< Date struct */ +typedef struct { + uint16_t Year; /*!< Years (1998 - 2099) */ + uint16_t Month; /*!< Months (1 - 12) */ + uint16_t Day; /*!< Days (1 - 31) */ + uint16_t DayOfWeek; /*!< Day of week (0-Sunday, .. 6-Saturday) */ +} LDD_TimeDate_TDateRec; + +/* +** =================================================================== +** UART device types and constants +** =================================================================== +*/ +#define LDD_SERIAL_RX_PIN 0x01u /*!< Receiver pin mask */ +#define LDD_SERIAL_TX_PIN 0x02u /*!< Transmitter pin mask */ +#define LDD_SERIAL_CTS_PIN 0x04u /*!< CTS pin mask */ +#define LDD_SERIAL_RTS_PIN 0x08u /*!< RTS pin mask */ + +#define LDD_SERIAL_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SERIAL_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SERIAL_ON_BREAK 0x04u /*!< OnBreak event mask */ +#define LDD_SERIAL_ON_TXCOMPLETE 0x08u /*!< OnTxComplete event mask */ +#define LDD_SERIAL_ON_ERROR 0x10u /*!< OnError event mask */ + +#define LDD_SERIAL_RX_OVERRUN 0x01u /*!< Receiver overrun */ +#define LDD_SERIAL_PARITY_ERROR 0x02u /*!< Parity error */ +#define LDD_SERIAL_FRAMING_ERROR 0x04u /*!< Framing error */ +#define LDD_SERIAL_NOISE_ERROR 0x08u /*!< Noise error */ + +typedef uint32_t LDD_SERIAL_TError; /*!< Serial communication error type */ + +typedef uint8_t LDD_SERIAL_TDataWidth; /*!< Bit length type. The number of bits transmitted by one character. */ + +typedef uint16_t LDD_SERIAL_TSize; /*!< Type specifying the length of the data or buffer. */ + +typedef uint8_t LDD_SERIAL_TBaudMode; /*!< Type specifying the baud mode. */ + +/*! Type specifying the parity. */ +typedef enum { + LDD_SERIAL_PARITY_UNDEF, /*!< Undefined parity */ + LDD_SERIAL_PARITY_NONE, /*!< Parity none */ + LDD_SERIAL_PARITY_ODD, /*!< Parity odd */ + LDD_SERIAL_PARITY_EVEN, /*!< Parity even */ + LDD_SERIAL_PARITY_MARK, /*!< Parity mark */ + LDD_SERIAL_PARITY_SPACE /*!< Parity space */ +} LDD_SERIAL_TParity; + +/*! Type specifying the stop bit length. */ +typedef enum { + LDD_SERIAL_STOP_BIT_LEN_UNDEF, /*!< Undefined bit length */ + LDD_SERIAL_STOP_BIT_LEN_1, /*!< 1 bit length */ + LDD_SERIAL_STOP_BIT_LEN_1_5, /*!< 1.5 bit length */ + LDD_SERIAL_STOP_BIT_LEN_2 /*!< 2 bit length */ +} LDD_SERIAL_TStopBitLen; + +/*! Communication statistics */ +typedef struct { + uint32_t ReceivedChars; /*!< Number of received characters */ + uint32_t SentChars; /*!< Number of transmitted characters */ + uint32_t ReceivedBreaks; /*!< Number of received break characters */ + uint32_t ParityErrors; /*!< Number of receiver parity errors */ + uint32_t FramingErrors; /*!< Number of receiver framing errors */ + uint32_t OverrunErrors; /*!< Number of receiver overrun errors */ + uint32_t NoiseErrors; /*!< Number of receiver noise errors */ +} LDD_SERIAL_TStats; + +/*! Type specifying the loop mode operation. */ +typedef enum { + LOOPMODE_UNDEF, /*!< Undefined loop mode */ + LOOPMODE_NORMAL, /*!< Normal operation */ + LOOPMODE_AUTO_ECHO, /*!< Auto echo mode */ + LOOPMODE_LOCAL_LOOPBACK, /*!< Local loopback mode */ + LOOPMODE_REMOTE_LOOPBACK /*!< Remote loopback mode */ +} LDD_SERIAL_TLoopMode; + + +/* +** =================================================================== +** ADC device types and constants +** =================================================================== +*/ + +#define LDD_ADC_CHANNEL_0_PIN 0x01u /*!< Channel 0 pin mask */ +#define LDD_ADC_CHANNEL_1_PIN 0x02u /*!< Channel 1 pin mask */ +#define LDD_ADC_CHANNEL_2_PIN 0x04u /*!< Channel 2 pin mask */ +#define LDD_ADC_CHANNEL_3_PIN 0x08u /*!< Channel 3 pin mask */ +#define LDD_ADC_CHANNEL_4_PIN 0x10u /*!< Channel 4 pin mask */ +#define LDD_ADC_CHANNEL_5_PIN 0x20u /*!< Channel 5 pin mask */ +#define LDD_ADC_CHANNEL_6_PIN 0x40u /*!< Channel 6 pin mask */ +#define LDD_ADC_CHANNEL_7_PIN 0x80u /*!< Channel 7 pin mask */ +#define LDD_ADC_CHANNEL_8_PIN 0x0100u /*!< Channel 8 pin mask */ +#define LDD_ADC_CHANNEL_9_PIN 0x0200u /*!< Channel 9 pin mask */ +#define LDD_ADC_CHANNEL_10_PIN 0x0400u /*!< Channel 10 pin mask */ +#define LDD_ADC_CHANNEL_11_PIN 0x0800u /*!< Channel 11 pin mask */ +#define LDD_ADC_CHANNEL_12_PIN 0x1000u /*!< Channel 12 pin mask */ +#define LDD_ADC_CHANNEL_13_PIN 0x2000u /*!< Channel 13 pin mask */ +#define LDD_ADC_CHANNEL_14_PIN 0x4000u /*!< Channel 14 pin mask */ +#define LDD_ADC_CHANNEL_15_PIN 0x8000u /*!< Channel 15 pin mask */ +#define LDD_ADC_CHANNEL_16_PIN 0x00010000u /*!< Channel 16 pin mask */ +#define LDD_ADC_CHANNEL_17_PIN 0x00020000u /*!< Channel 17 pin mask */ +#define LDD_ADC_CHANNEL_18_PIN 0x00040000u /*!< Channel 18 pin mask */ +#define LDD_ADC_CHANNEL_19_PIN 0x00080000u /*!< Channel 19 pin mask */ +#define LDD_ADC_CHANNEL_20_PIN 0x00100000u /*!< Channel 20 pin mask */ +#define LDD_ADC_CHANNEL_21_PIN 0x00200000u /*!< Channel 21 pin mask */ +#define LDD_ADC_CHANNEL_22_PIN 0x00400000u /*!< Channel 22 pin mask */ +#define LDD_ADC_CHANNEL_23_PIN 0x00800000u /*!< Channel 23 pin mask */ +#define LDD_ADC_CHANNEL_24_PIN 0x01000000u /*!< Channel 24 pin mask */ +#define LDD_ADC_CHANNEL_25_PIN 0x02000000u /*!< Channel 25 pin mask */ +#define LDD_ADC_CHANNEL_26_PIN 0x04000000u /*!< Channel 26 pin mask */ +#define LDD_ADC_CHANNEL_27_PIN 0x08000000u /*!< Channel 27 pin mask */ +#define LDD_ADC_CHANNEL_28_PIN 0x10000000u /*!< Channel 28 pin mask */ +#define LDD_ADC_CHANNEL_29_PIN 0x20000000u /*!< Channel 29 pin mask */ +#define LDD_ADC_CHANNEL_30_PIN 0x40000000u /*!< Channel 30 pin mask */ +#define LDD_ADC_CHANNEL_31_PIN 0x80000000u /*!< Channel 31 pin mask */ +#define LDD_ADC_CHANNEL_32_PIN 0x01u /*!< Channel 32 pin mask */ +#define LDD_ADC_CHANNEL_33_PIN 0x02u /*!< Channel 33 pin mask */ +#define LDD_ADC_CHANNEL_34_PIN 0x04u /*!< Channel 34 pin mask */ +#define LDD_ADC_CHANNEL_35_PIN 0x08u /*!< Channel 35 pin mask */ +#define LDD_ADC_CHANNEL_36_PIN 0x10u /*!< Channel 36 pin mask */ +#define LDD_ADC_CHANNEL_37_PIN 0x20u /*!< Channel 37 pin mask */ +#define LDD_ADC_CHANNEL_38_PIN 0x40u /*!< Channel 38 pin mask */ +#define LDD_ADC_CHANNEL_39_PIN 0x80u /*!< Channel 39 pin mask */ +#define LDD_ADC_CHANNEL_40_PIN 0x0100u /*!< Channel 40 pin mask */ +#define LDD_ADC_CHANNEL_41_PIN 0x0200u /*!< Channel 41 pin mask */ +#define LDD_ADC_CHANNEL_42_PIN 0x0400u /*!< Channel 42 pin mask */ +#define LDD_ADC_CHANNEL_43_PIN 0x0800u /*!< Channel 43 pin mask */ +#define LDD_ADC_CHANNEL_44_PIN 0x1000u /*!< Channel 44 pin mask */ +#define LDD_ADC_CHANNEL_45_PIN 0x2000u /*!< Channel 45 pin mask */ +#define LDD_ADC_CHANNEL_46_PIN 0x4000u /*!< Channel 46 pin mask */ +#define LDD_ADC_CHANNEL_47_PIN 0x8000u /*!< Channel 47 pin mask */ +#define LDD_ADC_CHANNEL_48_PIN 0x00010000u /*!< Channel 48 pin mask */ +#define LDD_ADC_CHANNEL_49_PIN 0x00020000u /*!< Channel 49 pin mask */ +#define LDD_ADC_CHANNEL_50_PIN 0x00040000u /*!< Channel 50 pin mask */ +#define LDD_ADC_CHANNEL_51_PIN 0x00080000u /*!< Channel 51 pin mask */ +#define LDD_ADC_CHANNEL_52_PIN 0x00100000u /*!< Channel 52 pin mask */ +#define LDD_ADC_CHANNEL_53_PIN 0x00200000u /*!< Channel 53 pin mask */ +#define LDD_ADC_CHANNEL_54_PIN 0x00400000u /*!< Channel 54 pin mask */ +#define LDD_ADC_CHANNEL_55_PIN 0x00800000u /*!< Channel 55 pin mask */ +#define LDD_ADC_CHANNEL_56_PIN 0x01000000u /*!< Channel 56 pin mask */ +#define LDD_ADC_CHANNEL_57_PIN 0x02000000u /*!< Channel 57 pin mask */ +#define LDD_ADC_CHANNEL_58_PIN 0x04000000u /*!< Channel 58 pin mask */ +#define LDD_ADC_CHANNEL_59_PIN 0x08000000u /*!< Channel 59 pin mask */ +#define LDD_ADC_CHANNEL_60_PIN 0x10000000u /*!< Channel 60 pin mask */ +#define LDD_ADC_CHANNEL_61_PIN 0x20000000u /*!< Channel 61 pin mask */ +#define LDD_ADC_CHANNEL_62_PIN 0x40000000u /*!< Channel 62 pin mask */ +#define LDD_ADC_CHANNEL_63_PIN 0x80000000u /*!< Channel 63 pin mask */ + +#define LDD_ADC_TRIGGER_0_PIN 0x01u /*!< Trigger 0 pin mask */ +#define LDD_ADC_TRIGGER_1_PIN 0x02u /*!< Trigger 1 pin mask */ + +#define LDD_ADC_LOW_VOLT_REF_PIN 0x01u /*!< Low voltage reference pin mask */ +#define LDD_ADC_HIGH_VOLT_REF_PIN 0x02u /*!< High voltage reference pin mask */ + +#define LDD_ADC_ON_MEASUREMENT_COMPLETE 0x40u /*!< OnMeasurementComplete event mask */ +#define LDD_ADC_ON_ERROR 0x80u /*!< OnError event mask */ + +#define LDD_ADC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef uint32_t LDD_ADC_TErrorMask; /*!< ADC error type */ + +/*! Structure pins for pin connection method */ +typedef struct { + uint32_t Channel0_31PinMask; /*!< Channel pin mask for channels 0 through 31 */ + uint32_t Channel32_63PinMask; /*!< Channel pin mask for channels 32 through 63 */ + uint16_t TriggerPinMask; /*!< Trigger pin mask */ + uint8_t VoltRefPinMask; /*!< Voltage reference pin mask */ +} LDD_ADC_TPinMask; + +/*! Structure used to describing one sample */ +typedef struct { + uint8_t ChannelIdx; /*!< Channel index */ +} LDD_ADC_TSample; + +/*! Type specifying the ADC compare mode */ +typedef enum { + LDD_ADC_LESS_THAN = 0x00u, /*!< Compare true if the result is less than the Low compare value */ + LDD_ADC_GREATER_THAN_OR_EQUAL = 0x01u, /*!< Compare true if the result is greater than or equal to Low compare value */ + LDD_ADC_INSIDE_RANGE_INCLUSIVE = 0x02u, /*!< Compare true if the result is greater than or equal to Low compare value and the result is less than or equal to High compare value */ + LDD_ADC_INSIDE_RANGE_NOT_INCLUSIVE = 0x03u, /*!< Compare true if the result is greater than Low compare value and the result is less than High compare value */ + LDD_ADC_OUTSIDE_RANGE_INCLUSIVE = 0x04u, /*!< Compare true if the result is less than or equal to Low compare value or the result is greater than or equal to High compare value */ + LDD_ADC_OUTSIDE_RANGE_NOT_INCLUSIVE = 0x05u /*!< Compare true if the result is less than Low compare value or the result is greater than High compare value */ +} LDD_ADC_TCompareMode; + +/* +** =================================================================== +** I2C device types and constants +** =================================================================== +*/ + +#define LDD_I2C_SDA_PIN 0x01u /*!< SDA pin mask */ +#define LDD_I2C_SCL_PIN 0x02u /*!< SCL pin mask */ + +#define LDD_I2C_ON_MASTER_BLOCK_SENT 0x0001u /*!< OnMasterBlockSent event mask */ +#define LDD_I2C_ON_MASTER_BLOCK_RECEIVED 0x0002u /*!< OnMasterBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_SENT 0x0004u /*!< OnSlaveBlockSent event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_RECEIVED 0x0008u /*!< OnSlaveBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_TX_REQUEST 0x0010u /*!< OnSlaveTxRequest event mask */ +#define LDD_I2C_ON_SLAVE_RX_REQUEST 0x0020u /*!< OnSlaveRxRequest event mask */ +#define LDD_I2C_ON_ERROR 0x0040u /*!< OnError event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_CALL_ADDR 0x0080u /*!< OnSlaveSMBusCallAddr event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_ALERT_RESPONSE 0x0100u /*!< OnSlaveSMBusAlertResponse event mask */ +#define LDD_I2C_ON_SLAVE_GENERAL_CALL_ADDR 0x0200u /*!< OnSlaveGeneralCallAddr event mask */ +#define LDD_I2C_ON_MASTER_BYTE_RECEIVED 0x0400u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_SLAVE_BYTE_RECEIVED 0x0800u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_BUS_START_DETECTED 0x1000u /*!< OnBusStartDetected event mask */ +#define LDD_I2C_ON_BUS_STOP_DETECTED 0x2000u /*!< OnBusStopDetected event mask */ + +#define LDD_I2C_SLAVE_TX_UNDERRUN 0x0001u /*!< SlaveTxUnderrun error mask */ +#define LDD_I2C_SLAVE_RX_OVERRUN 0x0002u /*!< SlaveRxOverrun error mask */ +#define LDD_I2C_ARBIT_LOST 0x0004u /*!< ArbitLost error mask */ +#define LDD_I2C_MASTER_NACK 0x0008u /*!< MasterNACK error mask */ +#define LDD_I2C_SCL_LOW_TIMEOUT 0x0010u /*!< SCLLowTimeout error mask */ +#define LDD_I2C_SDA_LOW_TIMEOUT 0x0020u /*!< SDALowTimeout error mask */ +#define LDD_I2C_SLAVE_NACK 0x0040u /*!< SlaveNACK error mask */ + +typedef uint16_t LDD_I2C_TSize; /*!< Type specifying the length of the data or buffer. */ +typedef uint16_t LDD_I2C_TAddr; /*!< Type specifying the address variable */ +typedef uint16_t LDD_I2C_TErrorMask; /*!< Type specifying the error mask type. */ +typedef bool LDD_I2C_TMode; /*!< Type specifynng the Actual operating mode */ + +/*! Type specifying the address type */ +typedef enum { + LDD_I2C_ADDRTYPE_7BITS, /*!< 7 bits address */ + LDD_I2C_ADDRTYPE_10BITS, /*!< 10 bits address */ + LDD_I2C_ADDRTYPE_GENERAL_CALL /*!< General call address */ +} LDD_I2C_TAddrType; + +/*! Type specifying generate the stop condition */ +typedef enum { + LDD_I2C_NO_SEND_STOP, /*!< Do not send stop signal */ + LDD_I2C_SEND_STOP /*!< Send stop signal */ +} LDD_I2C_TSendStop; + +/*! Type specifying the I2C state of BUS. */ +typedef enum { + LDD_I2C_BUSY, /*!< The bus is busy */ + LDD_I2C_IDLE /*!< The bus is idle */ +} LDD_I2C_TBusState; + +/*! Type specifying the I2C byte acknowledge response. */ +typedef enum { + LDD_I2C_ACK_BYTE, /*!< Byte acknowledged */ + LDD_I2C_NACK_BYTE /*!< Byte not acknowledged */ +} LDD_I2C_TAckType; + +/*! Communication statistics */ +typedef struct { + uint32_t MasterSentChars; /*!< Number of master transmitted characters. */ + uint32_t MasterReceivedChars; /*!< Number of master received characters. */ + uint32_t MasterNacks; /*!< Number of no acknowledges. */ + uint32_t ArbitLost; /*!< Number of lost the bus arbitration. */ + uint32_t SlaveSentChars; /*!< Number of slave transmitted characters. */ + uint32_t SlaveReceivedChars; /*!< Number of slave received characters. */ + uint32_t SlaveTxUnderrun; /*!< Number of slave underrun. */ + uint32_t SlaveRxOverrun; /*!< Number of slave overrun. */ + uint32_t SlaveGeneralCallAddr; /*!< Number of a general call address. */ + uint32_t SlaveSmBusCallAddr; /*!< Number of a SMBus call address. */ + uint32_t SlaveSmBusAlertResponse; /*!< Number of slave SMBus alert response received. */ + uint32_t SCLLowTimeout; /*!< Number of SCL low timeout occur. */ + uint32_t SDALowTimeout; /*!< Number of SCL low timeout occur. */ +} LDD_I2C_TStats; + + +/* +** =================================================================== +** SegLCD device types and constants +** =================================================================== +*/ + +#define LDD_SEGLCD_ON_FRAME_FREQUENCY 0x0001u /*!< OnFrameFrequency event mask */ +#define LDD_SEGLCD_ON_FAULT_DETECT_COMPLETE 0x0002u /*!< OnFaultDetectComplete event mask */ + +typedef uint8_t LDD_SegLCD_TPinIndex; /*!< Type specifying the segment LCD pin index variable */ +typedef uint8_t LDD_SegLCD_TFrontplaneData; /*!< Type specifying the frontplane/backplane segment variable */ +typedef uint8_t LDD_SegLCD_TFaultValue; /*!< Type specifying the frontplane/backplane segment variable */ + +/*! Types specifying the segment LCD blinking. */ +typedef enum { + LDD_SEGLCD_BLINK_OFF, /*!< Disables display blinking */ + LDD_SEGLCD_BLINK_ALL, /*!< Display blank during the blink period */ + LDD_SEGLCD_BLINK_ALL_ALTERNATE /*!< Blinking between alternate backplane */ +} LDD_SegLCD_TBlinking; + +/*! Segment LCD blank state type. */ +typedef enum { + LDD_SEGLCD_BLANK_STATE, /*!< Blank display mode */ + LDD_SEGLCD_NORMAL_STATE, /*!< Normal display mode */ + LDD_SEGLCD_ALTERNATE_STATE /*!< Alternate display mode */ +} LDD_SegLCD_TSetBlank; + +/*! Segment LCD pin type (frontplane/backplane) */ +typedef enum { + LDD_SEGLCD_BACKPLANE_PIN, /*!< Backplane pin */ + LDD_SEGLCD_FRONTPLANE_PIN /*!< Frontplane pin */ +} LDD_SegLCD_TPinType; + + +/* +** =================================================================== +** GPIO device types and constants +** =================================================================== +*/ + +#define LDD_GPIO_PIN_0 0x01u /*!< Pin 0 inside the port */ +#define LDD_GPIO_PIN_1 0x02u /*!< Pin 1 inside the port */ +#define LDD_GPIO_PIN_2 0x04u /*!< Pin 2 inside the port */ +#define LDD_GPIO_PIN_3 0x08u /*!< Pin 3 inside the port */ +#define LDD_GPIO_PIN_4 0x10u /*!< Pin 4 inside the port */ +#define LDD_GPIO_PIN_5 0x20u /*!< Pin 5 inside the port */ +#define LDD_GPIO_PIN_6 0x40u /*!< Pin 6 inside the port */ +#define LDD_GPIO_PIN_7 0x80u /*!< Pin 7 inside the port */ +#define LDD_GPIO_PIN_8 0x0100u /*!< Pin 8 inside the port */ +#define LDD_GPIO_PIN_9 0x0200u /*!< Pin 9 inside the port */ +#define LDD_GPIO_PIN_10 0x0400u /*!< Pin 10 inside the port */ +#define LDD_GPIO_PIN_11 0x0800u /*!< Pin 11 inside the port */ +#define LDD_GPIO_PIN_12 0x1000u /*!< Pin 12 inside the port */ +#define LDD_GPIO_PIN_13 0x2000u /*!< Pin 13 inside the port */ +#define LDD_GPIO_PIN_14 0x4000u /*!< Pin 14 inside the port */ +#define LDD_GPIO_PIN_15 0x8000u /*!< Pin 15 inside the port */ +#define LDD_GPIO_PIN_16 0x00010000u /*!< Pin 16 inside the port */ +#define LDD_GPIO_PIN_17 0x00020000u /*!< Pin 17 inside the port */ +#define LDD_GPIO_PIN_18 0x00040000u /*!< Pin 18 inside the port */ +#define LDD_GPIO_PIN_19 0x00080000u /*!< Pin 19 inside the port */ +#define LDD_GPIO_PIN_20 0x00100000u /*!< Pin 20 inside the port */ +#define LDD_GPIO_PIN_21 0x00200000u /*!< Pin 21 inside the port */ +#define LDD_GPIO_PIN_22 0x00400000u /*!< Pin 22 inside the port */ +#define LDD_GPIO_PIN_23 0x00800000u /*!< Pin 23 inside the port */ +#define LDD_GPIO_PIN_24 0x01000000u /*!< Pin 24 inside the port */ +#define LDD_GPIO_PIN_25 0x02000000u /*!< Pin 25 inside the port */ +#define LDD_GPIO_PIN_26 0x04000000u /*!< Pin 26 inside the port */ +#define LDD_GPIO_PIN_27 0x08000000u /*!< Pin 27 inside the port */ +#define LDD_GPIO_PIN_28 0x10000000u /*!< Pin 28 inside the port */ +#define LDD_GPIO_PIN_29 0x20000000u /*!< Pin 29 inside the port */ +#define LDD_GPIO_PIN_30 0x40000000u /*!< Pin 30 inside the port */ +#define LDD_GPIO_PIN_31 0x80000000u /*!< Pin 31 inside the port */ + +#define LDD_GPIO_ON_PORT_EVENT 0x01u /*!< OnPortEvent event mask */ + +typedef uint32_t LDD_GPIO_TBitField; /*!< Abstract type specifying the bit field within the port. */ + +/*! Defines condition when event is invoked. */ +typedef enum { + LDD_GPIO_DISABLED = 0x00u, /*!< Event doesn't invoke */ + LDD_GPIO_LOW = 0x00080000u, /*!< Event when logic zero */ + LDD_GPIO_HIGH = 0x000C0000u, /*!< Event when logic one */ + LDD_GPIO_RISING = 0x00090000u, /*!< Event on rising edge */ + LDD_GPIO_FALLING = 0x000A0000u, /*!< Event on falling edge */ + LDD_GPIO_BOTH = 0x000B0000u /*!< Event on rising and falling edge */ +} LDD_GPIO_TEventCondition; /*!< Defines condition when event is invoked. */ + +#define LDD_GPIO_EVENT_CONDITIONS_MASK 0x000F0000u + +/* +** =================================================================== +** BITSIO device types and constants +** =================================================================== +*/ +#define LDD_BITSIO_PIN_0 0x01U /*!< Pin 0 inside pin list of component */ +#define LDD_BITSIO_PIN_1 0x02U /*!< Pin 1 inside pin list of component */ +#define LDD_BITSIO_PIN_2 0x04U /*!< Pin 2 inside pin list of component */ +#define LDD_BITSIO_PIN_3 0x08U /*!< Pin 3 inside pin list of component */ +#define LDD_BITSIO_PIN_4 0x10U /*!< Pin 4 inside pin list of component */ +#define LDD_BITSIO_PIN_5 0x20U /*!< Pin 5 inside pin list of component */ +#define LDD_BITSIO_PIN_6 0x40U /*!< Pin 6 inside pin list of component */ +#define LDD_BITSIO_PIN_7 0x80U /*!< Pin 7 inside pin list of component */ +#define LDD_BITSIO_PIN_8 0x0100U /*!< Pin 8 inside pin list of component */ +#define LDD_BITSIO_PIN_9 0x0200U /*!< Pin 9 inside pin list of component */ +#define LDD_BITSIO_PIN_10 0x0400U /*!< Pin 10 inside pin list of component */ +#define LDD_BITSIO_PIN_11 0x0800U /*!< Pin 11 inside pin list of component */ +#define LDD_BITSIO_PIN_12 0x1000U /*!< Pin 12 inside pin list of component */ +#define LDD_BITSIO_PIN_13 0x2000U /*!< Pin 13 inside pin list of component */ +#define LDD_BITSIO_PIN_14 0x4000U /*!< Pin 14 inside pin list of component */ +#define LDD_BITSIO_PIN_15 0x8000U /*!< Pin 15 inside pin list of component */ +#define LDD_BITSIO_PIN_16 0x00010000U /*!< Pin 16 inside pin list of component */ +#define LDD_BITSIO_PIN_17 0x00020000U /*!< Pin 17 inside pin list of component */ +#define LDD_BITSIO_PIN_18 0x00040000U /*!< Pin 18 inside pin list of component */ +#define LDD_BITSIO_PIN_19 0x00080000U /*!< Pin 19 inside pin list of component */ +#define LDD_BITSIO_PIN_20 0x00100000U /*!< Pin 20 inside pin list of component */ +#define LDD_BITSIO_PIN_21 0x00200000U /*!< Pin 21 inside pin list of component */ +#define LDD_BITSIO_PIN_22 0x00400000U /*!< Pin 22 inside pin list of component */ +#define LDD_BITSIO_PIN_23 0x00800000U /*!< Pin 23 inside pin list of component */ +#define LDD_BITSIO_PIN_24 0x01000000U /*!< Pin 24 inside pin list of component */ +#define LDD_BITSIO_PIN_25 0x02000000U /*!< Pin 25 inside pin list of component */ +#define LDD_BITSIO_PIN_26 0x04000000U /*!< Pin 26 inside pin list of component */ +#define LDD_BITSIO_PIN_27 0x08000000U /*!< Pin 27 inside pin list of component */ +#define LDD_BITSIO_PIN_28 0x10000000U /*!< Pin 28 inside pin list of component */ +#define LDD_BITSIO_PIN_29 0x20000000U /*!< Pin 29 inside pin list of component */ +#define LDD_BITSIO_PIN_30 0x40000000U /*!< Pin 30 inside pin list of component */ +#define LDD_BITSIO_PIN_31 0x80000000U /*!< Pin 31 inside pin list of component */ + +/* +** =================================================================== +** Ethernet device types and constants +** =================================================================== +*/ + +#define LDD_ETH_MDC_PIN 0x01u /*!< MDC pin mask */ +#define LDD_ETH_MDIO_PIN 0x02u /*!< MDIO pin mask */ +#define LDD_ETH_COL_PIN 0x04u /*!< COL pin mask */ +#define LDD_ETH_CRS_PIN 0x08u /*!< CRS pin mask */ +#define LDD_ETH_TXCLK_PIN 0x10u /*!< TXCLK pin mask */ +#define LDD_ETH_TXD0_PIN 0x20u /*!< TXD0 pin mask */ +#define LDD_ETH_TXD1_PIN 0x40u /*!< TXD1 pin mask */ +#define LDD_ETH_TXD2_PIN 0x80u /*!< TXD2 pin mask */ +#define LDD_ETH_TXD3_PIN 0x0100u /*!< TXD3 pin mask */ +#define LDD_ETH_TXEN_PIN 0x0200u /*!< TXEN pin mask */ +#define LDD_ETH_TXER_PIN 0x0400u /*!< TXER pin mask */ +#define LDD_ETH_RXCLK_PIN 0x0800u /*!< RXCLK pin mask */ +#define LDD_ETH_RXDV_PIN 0x1000u /*!< RXDV pin mask */ +#define LDD_ETH_RXD0_PIN 0x2000u /*!< RXD0 pin mask */ +#define LDD_ETH_RXD1_PIN 0x4000u /*!< RXD1 pin mask */ +#define LDD_ETH_RXD2_PIN 0x8000u /*!< RXD2 pin mask */ +#define LDD_ETH_RXD3_PIN 0x00010000u /*!< RXD3 pin mask */ +#define LDD_ETH_RXER_PIN 0x00020000u /*!< RXER pin mask */ + +#define LDD_ETH_ON_FRAME_TRANSMITTED 0x01u /*!< OnFrameTransmitted event mask */ +#define LDD_ETH_ON_FRAME_TRANSMITTED_TIMESTAMPED 0x02u /*!< OnFrameTransmittedTimestamped event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED 0x04u /*!< OnFrameReceived event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED_TIMESTAMPED 0x08u /*!< OnFrameReceivedTimestamped event mask */ +#define LDD_ETH_ON_MII_FINISHED 0x10u /*!< OnMIIFinished event mask */ +#define LDD_ETH_ON_FATAL_ERROR 0x20u /*!< OnFatalError event mask */ +#define LDD_ETH_ON_WAKE_UP 0x40u /*!< OnWakeUp event mask */ + +typedef uint8_t LDD_ETH_TMACAddress[6]; /*!< Ethernet MAC address */ + +/*! Ethernet duplex mode */ +typedef enum { + LDD_ETH_FULL_DUPLEX, /*!< Full duplex mode */ + LDD_ETH_HALF_DUPLEX /*!< Half duplex mode */ +} LDD_ETH_TDuplexMode; + +/*! Ethernet address filter mode options */ +typedef enum { + LDD_ETH_PROMISC, /*!< Promiscuous mode */ + LDD_ETH_REJECT_BC, /*!< Reject broadcast frames */ + LDD_ETH_ACCEPT_BC /*!< Accept broadcast frames */ +} LDD_ETH_TFilterMode; + +/*! Ethernet sleep mode options */ +typedef enum { + LDD_ETH_ENABLED, /*!< Sleep mode enabled */ + LDD_ETH_ENABLED_WITH_WAKEUP, /*!< Sleep mode enabled, waiting for wake-up */ + LDD_ETH_DISABLED /*!< Sleep mode disabled */ +} LDD_ETH_TSleepMode; + +/*! Ethernet frame buffer (fragment) descriptor */ +typedef struct { + uint8_t *DataPtr; /*!< Pointer to buffer data */ + uint16_t Size; /*!< Buffer data size */ +} LDD_ETH_TBufferDesc; + +typedef LDD_ETH_TBufferDesc* LDD_ETH_TBufferDescPtr; /*!< Frame buffer descriptor pointer type */ + +/*! Ethernet communication statistics */ +typedef struct { + uint32_t TxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t TxRMONOctets; /*!< Octet count for frames transmitted without error */ + uint32_t TxRMONPackets; /*!< Transmitted packet count */ + uint32_t TxRMONBroadcastPackets; /*!< Transmitted broadcast packets */ + uint32_t TxRMONMulticastPackets; /*!< Transmitted multicast packets */ + uint32_t TxRMONCRCAlignErrors; /*!< Transmitted packets with CRC or alignment error */ + uint32_t TxRMONUndersizePackets; /*!< Transmitted packets smaller than 64 bytes with good CRC */ + uint32_t TxRMONOversizePackets; /*!< Transmitted packets greater than max. frame length with good CRC */ + uint32_t TxRMONFragments; /*!< Transmitted packets smaller than 64 bytes with bad CRC */ + uint32_t TxRMONJabbers; /*!< Transmitted packets greater than max. frame length with bad CRC */ + uint32_t TxRMONCollisions; /*!< Transmit collision count */ + uint32_t TxRMONPackets64Octets; /*!< Transmitted 64 byte packets */ + uint32_t TxRMONPackets65To127Octets; /*!< Transmitted 65 to 127 byte packets */ + uint32_t TxRMONPackets128To255Octets; /*!< Transmitted 128 to 255 byte packets */ + uint32_t TxRMONPackets256To511Octets; /*!< Transmitted 256 to 511 byte packets */ + uint32_t TxRMONPackets512To1023Octets; /*!< Transmitted 512 to 1023 byte packets */ + uint32_t TxRMONPackets1024To2047Octets; /*!< Transmitted 1024 to 2047 byte packets */ + uint32_t TxRMONPacketsGreaterThan2048Octets; /*!< Transmitted packets greater than 2048 byte */ + uint32_t TxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t TxIEEEFrameOK; /*!< Frames transmitted OK */ + uint32_t TxIEEESingleCollision; /*!< Frames transmitted with single collision */ + uint32_t TxIEEEMultipleCollisions; /*!< Frames transmitted with multiple collisions */ + uint32_t TxIEEEDeferralDelay; /*!< Frames transmitted after deferral delay */ + uint32_t TxIEEELateCollision; /*!< Frames transmitted with late collision */ + uint32_t TxIEEEExcessiveCollision; /*!< Frames transmitted with excessive collisions */ + uint32_t TxIEEEFIFOUnderrun; /*!< Frames transmitted with transmit FIFO underrun */ + uint32_t TxIEEECarrierSenseError; /*!< Frames transmitted with carrier sense error */ + uint32_t TxIEEESQEError; /*!< Frames transmitted with SQE error */ + uint32_t TxIEEEPauseFrame; /*!< Flow control pause frames transmitted */ + uint32_t TxIEEEOctetsOK; /*!< Octet count for frames transmitted without error */ + uint32_t RxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t RxRMONOctets; /*!< Octet count for frames recieved without error */ + uint32_t RxRMONPackets; /*!< Received packet count */ + uint32_t RxRMONBroadcastPackets; /*!< Received broadcast packets */ + uint32_t RxRMONMulticastPackets; /*!< Received multicast packets */ + uint32_t RxRMONCRCAlignErrors; /*!< Received packets with CRC or alignment error */ + uint32_t RxRMONUndersizePackets; /*!< Received packets smaller than 64 bytes with good CRC */ + uint32_t RxRMONOversizePackets; /*!< Received packets greater than max. frame length with good CRC */ + uint32_t RxRMONFragments; /*!< Received packets smaller than 64 bytes with bad CRC */ + uint32_t RxRMONJabbers; /*!< Received packets greater than max. frame length with bad CRC */ + uint32_t RxRMONPackets64Octets; /*!< Received 64 byte packets */ + uint32_t RxRMONPackets65To127Octets; /*!< Received 65 to 127 byte packets */ + uint32_t RxRMONPackets128To255Octets; /*!< Received 128 to 255 byte packets */ + uint32_t RxRMONPackets256To511Octets; /*!< Received 256 to 511 byte packets */ + uint32_t RxRMONPackets512To1023Octets; /*!< Received 512 to 1023 byte packets */ + uint32_t RxRMONPackets1024To2047Octets; /*!< Received 1024 to 2047 byte packets */ + uint32_t RxRMONPacketsGreaterThan2048Octets; /*!< Received packets greater than 2048 byte */ + uint32_t RxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t RxIEEEFrameOK; /*!< Frames received OK */ + uint32_t RxIEEECRCError; /*!< Frames received with CRC error */ + uint32_t RxIEEEAlignmentError; /*!< Frames received with alignment error */ + uint32_t RxIEEEFIFOOverflow; /*!< Receive FIFO overflow count */ + uint32_t RxIEEEPauseFrame; /*!< Flow control pause frames received */ + uint32_t RxIEEEOctetsOK; /*!< Octet count for frames received without error */ +} LDD_ETH_TStats; + +/* +** =================================================================== +** FlexCAN device types and constants +** =================================================================== +*/ + +typedef uint8_t LDD_CAN_TMBIndex; /*!< CAN message buffer index */ +typedef uint32_t LDD_CAN_TAccMask; /*!< Type specifying the acceptance mask variable. */ +typedef uint32_t LDD_CAN_TMessageID; /*!< Type specifying the ID mask variable. */ +typedef uint8_t LDD_CAN_TErrorCounter; /*!< Type specifying the error counter variable. */ +typedef uint32_t LDD_CAN_TErrorMask; /*!< Type specifying the error mask variable. */ +typedef uint16_t LDD_CAN_TBufferMask; /*!< Type specifying the message buffer mask variable. */ +#define LDD_CAN_RX_PIN 0x01U /*!< Rx pin mask */ +#define LDD_CAN_TX_PIN 0x02U /*!< Tx pin mask */ + +#define LDD_CAN_ON_FULL_RXBUFFER 0x01U /*!< OnFullRxBuffer event mask */ +#define LDD_CAN_ON_FREE_TXBUFFER 0x02U /*!< OnFreeTxBuffer event mask */ +#define LDD_CAN_ON_BUSOFF 0x04U /*!< OnBusOff event mask */ +#define LDD_CAN_ON_TXWARNING 0x08U /*!< OnTransmitterWarning event mask */ +#define LDD_CAN_ON_RXWARNING 0x10U /*!< OnReceiverWarning event mask */ +#define LDD_CAN_ON_ERROR 0x20U /*!< OnError event mask */ +#define LDD_CAN_ON_WAKEUP 0x40U /*!< OnWakeUp event mask */ + +#define LDD_CAN_BIT0_ERROR 0x4000UL /*!< Bit0 error detect error mask */ +#define LDD_CAN_BIT1_ERROR 0x8000UL /*!< Bit1 error detect error mask */ +#define LDD_CAN_ACK_ERROR 0x2000UL /*!< Acknowledge error detect error mask */ +#define LDD_CAN_CRC_ERROR 0x1000UL /*!< Cyclic redundancy check error detect error mask */ +#define LDD_CAN_FORM_ERROR 0x0800UL /*!< Message form error detect error mask */ +#define LDD_CAN_STUFFING_ERROR 0x0400UL /*!< Bit stuff error detect error mask */ + +#define LDD_CAN_MESSAGE_ID_EXT 0x80000000UL /*!< Value specifying extended Mask, ID */ + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_MB_RX_NOT_ACTIVE = 0x00U, + LDD_CAN_MB_RX_FULL = 0x02U, + LDD_CAN_MB_RX_EMPTY = 0x04U, + LDD_CAN_MB_RX_OVERRUN = 0x06U, + LDD_CAN_MB_RX_BUSY = 0x01U, + LDD_CAN_MB_RX_RANSWER = 0x0AU +} LDD_CAN_TRxBufferState; + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_DATA_FRAME, /*!< Data frame type received or transmitted */ + LDD_CAN_REMOTE_FRAME, /*!< Remote frame type */ + LDD_CAN_RESPONSE_FRAME /*!< Response frame type - Tx buffer send data after receiving remote frame with the same ID */ +} LDD_CAN_TFrameType; + +/*! Type specifying the CAN communication statistics. */ +typedef struct { + uint32_t TxFrames; /*!< Transmitted frame counter */ + uint32_t TxWarnings; /*!< Transmission warning counter */ + uint32_t RxFrames; /*!< Received frame counter */ + uint32_t RxWarnings; /*!< Reception warning counter */ + uint32_t BusOffs; /*!< Bus off counter */ + uint32_t Wakeups; /*!< Wakeup counter */ + uint32_t Bit0Errors; /*!< Bit0 error counter */ + uint32_t Bit1Errors; /*!< Bit1 error counter */ + uint32_t AckErrors; /*!< ACK error counter */ + uint32_t CrcErrors; /*!< CRC error counter */ + uint32_t FormErrors; /*!< Message form error counter */ + uint32_t BitStuffErrors; /*!< Bit stuff error counter */ + uint32_t Errors; /*!< Error counter */ +} LDD_CAN_TStats; + +/*! Type specifying the CAN frame features. */ +typedef struct { + LDD_CAN_TMessageID MessageID; /*!< Message ID */ + LDD_CAN_TFrameType FrameType; /*!< Type of the frame DATA/REMOTE */ + uint8_t *Data; /*!< Message data buffer */ + uint8_t Length; /*!< Message length */ + uint16_t TimeStamp; /*!< Message time stamp */ + uint8_t LocPriority; /*!< Local Priority Tx Buffers */ +} LDD_CAN_TFrame; + +/* +** =================================================================== +** USB device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_USB_ON_DEVICE_RESET 0x00000001u /*!< OnDeviceReset event mask */ +#define LDD_USB_ON_DEVICE_SPEED_DETECT 0x00000002u /*!< OnDeviceSpeedDetect event mask */ +#define LDD_USB_ON_DEVICE_SUSPEND 0x00000004u /*!< OnDeviceSuspend event mask */ +#define LDD_USB_ON_DEVICE_RESUME 0x00000008u /*!< OnDeviceResume event mask */ +#define LDD_USB_ON_DEVICE_SETUP_PACKET 0x00000010u /*!< OnDeviceSetupPacket event mask */ +#define LDD_USB_ON_DEVICE_SOF 0x00000020u /*!< OnDeviceSof event mask */ +#define LDD_USB_ON_DEVICE_1MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_1_MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_ERROR 0x00000080u /*!< OnDeviceError event mask */ +#define LDD_USB_ON_HOST_DEVICE_DEATTACH 0x00000100u /*!< OnHostDeviceAttach event mask */ +#define LDD_USB_ON_HOST_RESET_RECOVERY 0x00000200u /*!< OnHostResetRecovery event mask */ +#define LDD_USB_ON_HOST_RESUME_RECOVERY 0x00000400u /*!< OnHostResumeRecovery event mask */ +#define LDD_USB_ON_HOST_1MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_1_MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_ERROR 0x00001000u /*!< OnHostError event mask */ +#define LDD_USB_ON_OTG_DEVICE 0x00002000u /*!< OnOtgDevice event mask */ +#define LDD_USB_ON_OTG_HOST 0x00004000u /*!< OnOtgHost event mask */ +#define LDD_USB_ON_OTG_STATE_CHANGE 0x00008000u /*!< OnOtgStageChange event mask */ +#define LDD_USB_ON_SIGNAL_CHANGE 0x00010000u /*!< OnSignalChange event mask */ + +/* Data pins' masks */ +#define LDD_USB_DP_PIN 0x00000001u /*!< Data+ pin mask */ +#define LDD_USB_DM_PIN 0x00000002u /*!< Data- pin mask */ + +/* Pullup/pulldown pin masks */ +#define LDD_USB_DP_PU_PIN 0x00000004u /*!< Data+ pull-up pin mask */ +#define LDD_USB_DM_PU_PIN 0x00000008u /*!< Data- pull-up pin mask */ +#define LDD_USB_DP_PD_PIN 0x00000010u /*!< Data+ pull-down pin mask */ +#define LDD_USB_DM_PD_PIN 0x00000020u /*!< Data- pull-down pin mask */ + +/* VBUS pins' mask */ +#define LDD_USB_DEVICE_VBUS_DETECT_PIN 0x00000040u /*!< VBUS detect pin mask */ +#define LDD_USB_HOST_VBUS_ENABLE_PIN 0x00000080u /*!< VBUS enable pin mask */ +#define LDD_USB_HOST_VBUS_OVERCURRENT_PIN 0x00000100u /*!< VBUS overcurrent pin mask */ + +/* OTG pins' masks */ +#define LDD_USB_OTG_ID_PIN 0x00000200u /*!< ID pin mask */ +#define LDD_USB_OTG_VBUS_VALID_PIN 0x00000400u /*!< VBUS valid pin mask */ +#define LDD_USB_OTG_SESSION_VALID_PIN 0x00000800u /*!< SESSION valid pin mask */ +#define LDD_USB_OTG_B_SESSION_END_PIN 0x00004000u /*!< B SESSION end pin mask */ +#define LDD_USB_OTG_VBUS_ENABLE_PIN 0x00008000u /*!< VBUS drive pin mask */ +#define LDD_USB_OTG_VBUS_CHARGE_PIN 0x00010000u /*!< VBUS charge pin mask */ +#define LDD_USB_OTG_VBUS_DISCHARGE_PIN 0x00020000u /*!< VBUS discharge pin mask */ + +/* ULPI pins' masks */ +#define LDD_USB_ULPI_CLK_PIN 0x00080000u /*!< ULPI_CLK pin mask */ +#define LDD_USB_ULPI_DIR_PIN 0x00100000u /*!< ULPI_DIR pin mask */ +#define LDD_USB_ULPI_NXT_PIN 0x00200000u /*!< ULPI_NXT pin mask */ +#define LDD_USB_ULPI_STP_PIN 0x00400000u /*!< ULPI_STOP pin mask */ +#define LDD_USB_ULPI_DATA_0_PIN 0x00800000u /*!< ULPI_DATA_0 pin mask */ +#define LDD_USB_ULPI_DATA_1_PIN 0x01000000u /*!< ULPI_DATA_1 pin mask */ +#define LDD_USB_ULPI_DATA_2_PIN 0x02000000u /*!< ULPI_DATA_2 pin mask */ +#define LDD_USB_ULPI_DATA_3_PIN 0x04000000u /*!< ULPI_DATA_3 pin mask */ +#define LDD_USB_ULPI_DATA_4_PIN 0x08000000u /*!< ULPI_DATA_4 pin mask */ +#define LDD_USB_ULPI_DATA_5_PIN 0x10000000u /*!< ULPI_DATA_5 pin mask */ +#define LDD_USB_ULPI_DATA_6_PIN 0x20000000u /*!< ULPI_DATA_6 pin mask */ +#define LDD_USB_ULPI_DATA_7_PIN 0x40000000u /*!< ULPI_DATA_7 pin mask */ + +/* Alternate clock pin*/ +#define LDD_USB_CLKIN_PIN 0x80000000u /*!< Alternate clock pin mask */ +#define LDD_USB_ALT_CLK_PIN 0x80000000u /*!< Alternate clock pin mask */ + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Cmd/CmdStatusPtr param. values */ +#define LDD_USB_CMD_GET_EP_STATUS 0x00u /*!< Get endpoint status command ID */ +#define LDD_USB_CMD_SET_EP_HALT_FATURE 0x01u /*!< Set endpoint HALT feature command ID */ +#define LDD_USB_CMD_CLR_EP_HALT_FATURE 0x02u /*!< Clear endpoint HALT feature command ID */ + +#define LDD_USB_CMD_EP_STATUS_HALT_MASK 0x01u /*!< Endpoint halt status mask */ + + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Recipient param. values */ +/* (see USB 2.0, chapter 9.3.4 wIndex description)*/ +#define LDD_USB_ID_EP0_OUT 0x00u /*!< EP0 OUT component ID */ +#define LDD_USB_ID_EP0_IN 0x80u /*!< EP0 IN component ID */ +#define LDD_USB_ID_EP1_OUT 0x01u /*!< EP1 OUT component ID */ +#define LDD_USB_ID_EP1_IN 0x81u /*!< EP1 IN component ID */ +#define LDD_USB_ID_EP2_OUT 0x02u /*!< EP2 OUT component ID */ +#define LDD_USB_ID_EP2_IN 0x82u /*!< EP2 IN component ID */ +#define LDD_USB_ID_EP3_OUT 0x03u /*!< EP3 OUT component ID */ +#define LDD_USB_ID_EP3_IN 0x83u /*!< EP3 IN component ID */ +#define LDD_USB_ID_EP4_OUT 0x04u /*!< EP4 OUT component ID */ +#define LDD_USB_ID_EP4_IN 0x84u /*!< EP4 IN component ID */ +#define LDD_USB_ID_EP5_OUT 0x05u /*!< EP5 OUT component ID */ +#define LDD_USB_ID_EP5_IN 0x85u /*!< EP5 IN component ID */ +#define LDD_USB_ID_EP6_OUT 0x06u /*!< EP6 OUT component ID */ +#define LDD_USB_ID_EP6_IN 0x86u /*!< EP6 IN component ID */ +#define LDD_USB_ID_EP7_OUT 0x07u /*!< EP7 OUT component ID */ +#define LDD_USB_ID_EP7_IN 0x87u /*!< EP7 IN component ID */ +#define LDD_USB_ID_EP8_OUT 0x08u /*!< EP8 OUT component ID */ +#define LDD_USB_ID_EP8_IN 0x88u /*!< EP8 IN component ID */ +#define LDD_USB_ID_EP9_OUT 0x09u /*!< EP9 OUT component ID */ +#define LDD_USB_ID_EP9_IN 0x89u /*!< EP9 IN component ID */ +#define LDD_USB_ID_EP10_OUT 0x0Au /*!< EP10 OUT component ID */ +#define LDD_USB_ID_EP10_IN 0x8Au /*!< EP10 IN component ID */ +#define LDD_USB_ID_EP11_OUT 0x0Bu /*!< EP11 OUT component ID */ +#define LDD_USB_ID_EP11_IN 0x8Bu /*!< EP11 IN component ID */ +#define LDD_USB_ID_EP12_OUT 0x0Cu /*!< EP12 OUT component ID */ +#define LDD_USB_ID_EP12_IN 0x8Cu /*!< EP12 IN component ID */ +#define LDD_USB_ID_EP13_OUT 0x0Du /*!< EP13 OUT component ID */ +#define LDD_USB_ID_EP13_IN 0x8Du /*!< EP13 IN component ID */ +#define LDD_USB_ID_EP14_OUT 0x0Eu /*!< EP14 OUT component ID */ +#define LDD_USB_ID_EP14_IN 0x8Eu /*!< EP14 IN component ID */ +#define LDD_USB_ID_EP15_OUT 0x0Fu /*!< EP15 OUT component ID */ +#define LDD_USB_ID_EP15_IN 0x8Fu /*!< EP15 IN component ID */ +#define LDD_USB_ID_EP_MASK 0x8Fu /*!< EP15 IN component ID */ + +/* Token PID */ +#define LDD_USB_PID_OUT 0x01u /*!< OUT */ +#define LDD_USB_PID_IN 0x09u /*!< IN */ +#define LDD_USB_PID_SOF 0x05u /*!< SOF */ +#define LDD_USB_PID_SETUP 0x0Du /*!< SETUP */ +/* Data PID */ +#define LDD_USB_PID_DATA0 0x03u /*!< DATA0 */ +#define LDD_USB_PID_DATA1 0x0Bu /*!< DATA1 */ +#define LDD_USB_PID_DATA2 0x07u /*!< DATA2 */ +#define LDD_USB_PID_MDATA 0x0Fu /*!< MDATA */ +/* Handshake PID */ +#define LDD_USB_PID_ACK 0x02u /*!< ACK */ +#define LDD_USB_PID_NACK 0x0Au /*!< NACK */ +#define LDD_USB_PID_STALL 0x0Eu /*!< STALL */ +#define LDD_USB_PID_NYET 0x06u /*!< NYET */ +/* Special PID */ +#define LDD_USB_PID_PRE 0x0Cu /*!< PRE */ +#define LDD_USB_PID_ERR 0x0Cu /*!< ERR */ +#define LDD_USB_PID_SPLIT 0x08u /*!< SPLIT */ +#define LDD_USB_PID_PING 0x04u /*!< PING */ + +/* Data direction */ +#define LDD_USB_DIR_OUT 0x00u /*!< Recipient is Device */ +#define LDD_USB_DIR_IN 0x80u /*!< Recipient is Host */ +#define LDD_USB_DIR_MASK 0x80u /*!< Bit mask for data transfer direction */ + +/* Flags used in the TD.Head.Flags variable */ + +/* The following flag can be used to force zero-length termination(ZLT) of the transfer. + Note: ZLT can be set for all transfer during the initialization of the endpoint. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_ZLT 0x01u + +/* If the TRANSFER_FLAG_EXT_PARAM is defined all variables of the TD are used + and TD must NOT be freed until transfer is done or is cancelled + (TransferState != LDD_USB_TRANSFER_PENDING) + If not defined only the Head member of TD is used and TD can be freed after + Send/Recv() method returns. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM 0x02u + + +#define ERR_COMPONET_SPECIFIC 0x100u + +/* Device mode USB specific error codes */ +#define ERR_USB_DEVICE_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Device mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_DEVICE_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Device mode is disabled by the OTG driver */ +#define ERR_USB_DEVICE_VBUS_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< No VBUS is detected */ +#define ERR_USB_DEVICE_VBUS_ON (ERR_COMPONET_SPECIFIC + 0x03u) /*!< VBUS is detected */ +#define ERR_USB_DEVICE_ENABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is enabled */ +#define ERR_USB_DEVICE_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Device is suspended */ +#define ERR_USB_DEVICE_SUSPENDED_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Device is suspended and ready to generate resume signaling */ +#define ERR_USB_DEVICE_RESUME_PENDING (ERR_COMPONET_SPECIFIC + 0x07u) /*!< Device generates resume signaling */ + +/* Host mode USB specific error codes */ +#define ERR_USB_HOST_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Host mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_HOST_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Host mode is disabled by the OTG driver */ +#define ERR_USB_HOST_PORT_POWERED_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< Port is power off */ +#define ERR_USB_HOST_PORT_DISCONNECTED (ERR_COMPONET_SPECIFIC + 0x03u) /*!< Port is power on */ +#define ERR_USB_HOST_PORT_DISABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is connected to the port */ +#define ERR_USB_HOST_PORT_RESETING (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Port generates reset signaling */ +#define ERR_USB_HOST_PORT_RESET_RECOVERING (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Port waits 10ms for reset recovery */ +#define ERR_USB_HOST_PORT_ENABLED (ERR_COMPONET_SPECIFIC + 0x07u) /*!< PortDevice is connected, reset and ready to use */ +#define ERR_USB_HOST_PORT_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x08u) /*!< Port is suspended */ +#define ERR_USB_HOST_PORT_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x09u) /*!< Port can generate resume signaling */ +#define ERR_USB_HOST_PORT_RESUMING (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< Port generates resume signaling */ +#define ERR_USB_HOST_PORT_RESUME_RECOVERING (ERR_COMPONET_SPECIFIC + 0x0Bu) /*!< Port generates resume signaling */ + +/* OTG mode USB specific error codes */ +#define ERR_USB_OTG_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< OTG device is DISABLED state */ +#define ERR_USB_OTG_ENABLED_PENDING (ERR_COMPONET_SPECIFIC + 0x01u) /*!< OTG device is in ENABLED_PENDING state */ +#define ERR_USB_OTG_A_IDLE (ERR_COMPONET_SPECIFIC + 0x02u) /*!< OTG device is in A_IDLE state */ +#define ERR_USB_OTG_A_WAIT_VRISE (ERR_COMPONET_SPECIFIC + 0x03u) /*!< OTG device is in WAIT_VRISE state */ +#define ERR_USB_OTG_A_WAIT_VFALL (ERR_COMPONET_SPECIFIC + 0x05u) /*!< OTG device is in A_WAIT_VFALL state */ +#define ERR_USB_OTG_A_WAIT_BCON (ERR_COMPONET_SPECIFIC + 0x07u) /*!< OTG device is in A_WAIT_BCON state */ +#define ERR_USB_OTG_A_VBUS_ERROR (ERR_COMPONET_SPECIFIC + 0x09u) /*!< OTG device is in A_VBUS_ERROR state */ +#define ERR_USB_OTG_A_SUSPEND (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< OTG device is in A_SUSPEND state */ + +#define ERR_USB_OTG_B_IDLE (ERR_COMPONET_SPECIFIC + 0x0Cu) /*!< OTG device is in B_IDLE state */ +#define ERR_USB_OTG_B_SRP_INIT (ERR_COMPONET_SPECIFIC + 0x0Eu) /*!< OTG device is in B_SRP_INIT state */ +#define ERR_USB_OTG_B_WAIT_ACON (ERR_COMPONET_SPECIFIC + 0x0Fu) /*!< OTG device is in B_WAIT_ACON state */ + +#define ERR_USB_OTG_A_HOST (ERR_COMPONET_SPECIFIC + 0x10u) /*!< OTG device is in A_HOST state */ +#define ERR_USB_OTG_A_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x11u) /*!< OTG device is in A_PERIPHERAL state */ +#define ERR_USB_OTG_B_HOST (ERR_COMPONET_SPECIFIC + 0x12u) /*!< OTG device is in B_HOST state */ +#define ERR_USB_OTG_B_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x13u) /*!< OTG device is in B_PERIPHERAL state */ + +/*! Device speed symbolic names */ +typedef enum { + LDD_USB_LOW_SPEED = 0x00u, /*!< Low-speed - 6 Mb/s mode */ + LDD_USB_FULL_SPEED = 0x01u, /*!< Full-speed - 12 Mb/s mode */ + LDD_USB_HIGH_SPEED = 0x02u, /*!< High-speed - 480 Mb/s mode */ + LDD_USB_SPEED_UNKNOWN = 0xFFu /*!< Unkown speed mode */ +} LDD_USB_TBusSpeed; + +/*! Transfer type symbolic names */ +typedef enum { + LDD_USB_CONTROL = 0x00u, /*!< Conrol transfer type */ + LDD_USB_ISOCHRONOUS = 0x01u, /*!< Isochronous transfer type */ + LDD_USB_BULK = 0x02u, /*!< Bulk transfer type */ + LDD_USB_INTERRUPT = 0x03u /*!< Interrupt transfer type */ +} LDD_USB_TTransferType; + +/*! Transfer state symbolic names */ +typedef enum { + LDD_USB_TRANSFER_NONE = 0x00u, /*!< Default valeu for new TD */ + LDD_USB_TRANSFER_DONE = 0x01u, /*!< Transfer done */ + LDD_USB_TRANSFER_ERROR_CANCELLED = 0x02u, /*!< Transfer cancelled by the user */ + LDD_USB_TRANSFER_ERROR_STALLED = 0x03u, /*!< Transfer stalled */ + LDD_USB_TRANSFER_ERROR_BUS_TIMEOUT = 0x04u, /*!< Bus timeute detected */ + LDD_USB_TRANSFER_ERROR_DATA = 0x05u, /*!< Data error deteceted */ + LDD_USB_TRANSFER_ERROR_PID = 0x06u, /*!< PID error deteceted */ + LDD_USB_TRANSFER_ERROR_EOF = 0x07u, /*!< EOF error deteceted */ + LDD_USB_TRANSFER_ERROR_CRC16 = 0x08u, /*!< CRC16 error deteceted */ + LDD_USB_TRANSFER_ERROR_DFN8 = 0x09u, /*!< DFN8 error deteceted */ + LDD_USB_TRANSFER_ERROR_DMA = 0x0Au, /*!< DMA error deteceted */ + LDD_USB_TRANSFER_ERROR_BTS = 0x0Bu, /*!< BTS error deteceted */ + LDD_USB_TRANSFER_ERROR = 0x0Fu, /*!< Transfer error deteceted */ + LDD_USB_TRANSFER_QUEUED = 0x10u, /*!< Transfer queued */ + LDD_USB_TRANSFER_PENDING = 0x30u /*!< Transfer in proggress */ +} LDD_USB_TTransferState; + +/*! Setup data packet structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TSDP_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request code */ + uint16_t wValue; /*!< Word-sized field that varies according to request */ + uint16_t wIndex; /*!< Word-sized field that varies according to request, typically used to pass an index or offset */ + uint16_t wLength; /*!< Number of bytes to transfer if there is a data stage */ +} LDD_USB_TSDP; + +/*! Endpoint descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TEpDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint8_t bEndpointAddress; /*!< Endpoint address */ + uint8_t bmAttributes; /*!< Endpoint attributes */ + uint16_t wMaxPacketSize; /*!< Maximum packet size the endpoint is capable of sending or receiving */ + uint8_t bInterval; /*!< Interval for polling endpoint for data transfers */ +} LDD_USB_TEpDescriptor; + +/*! Standard device descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TDevDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t bcdUSB; /*!< USB specification release number in binary-coded Decimal */ + uint8_t bDeviceClass; /*!< Class code (assigned by the USB-IF) */ + uint8_t bDeviceSubClass; /*!< Subclass code (assigned by the USB-IF) */ + uint8_t bDeviceProtocol; /*!< Protocol code (assigned by the USB-IF) */ + uint8_t bMaxPacketSize0; /*!< Maximum packet size for endpoint zero */ + uint16_t idVendor; /*!< Vendor ID (assigned by the USB-IF) */ + uint16_t idProduct; /*!< Product ID (assigned by the manufacturer) */ + uint16_t bcdDevice; /*!< Device release number in binary-coded decimal */ + uint8_t iManufacturer; /*!< Index of string descriptor describing manufacturer */ + uint8_t iProduct; /*!< Index of string descriptor describing product */ + uint8_t iSerialNumber; /*!< Index of string descriptor describing the device’s serial number */ + uint8_t bNumConfigurations; /*!< Number of possible configurations */ +} LDD_USB_TDevDescriptor; + + +/*! Device transfer descriptor structure forward declaration */ +struct LDD_USB_Device_TTD_Struct; + +/*! Device transfer done callback prototype */ +typedef void (LDD_USB_Device_TTransferDoneCalback)(LDD_TDeviceData *DevDataPtr, struct LDD_USB_Device_TTD_Struct *TrParamPtr); + +/*! Device transfer descriptor structure - head part */ +typedef struct LDD_USB_Device_TTD_Head_Struct { + uint8_t EpNum; /*!< Endpoint number */ + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags - see constants definition */ +} LDD_USB_Device_TTD_Head; + +/*! Device transfer descriptor structure */ +typedef struct LDD_USB_Device_TTD_Struct { + /* Requierd variables */ + LDD_USB_Device_TTD_Head Head; /*!< Td head data, not changed by the driver */ + /* Optional items - the following items are used */ + /* only if Head.Flags & LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM != 0 */ + LDD_USB_TTransferState TransferState; /*!< Transfer state. Set by the driver */ + uint16_t TransmittedDataSize; /*!< Transmitted data size. Set by the driver */ + LDD_USB_Device_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ +} LDD_USB_Device_TTD; + +/*! USB device states symbolic names */ +typedef enum { + LDD_USB_DEVICE_DISABLED = ERR_USB_DEVICE_DISABLED, /*!< Device mode is disabled (by the user or by the clock configuration) */ + LDD_USB_DEVICE_DISABLED_BY_OTG = ERR_USB_DEVICE_DISABLED_BY_OTG, /*!< Device mode is disabled by the OTG driver */ + LDD_USB_DEVICE_VBUS_OFF = ERR_USB_DEVICE_VBUS_OFF, /*!< No VBUS is detected */ + LDD_USB_DEVICE_VBUS_ON = ERR_USB_DEVICE_VBUS_ON, /*!< VBUS is detected */ + LDD_USB_DEVICE_ENABLED = ERR_USB_DEVICE_ENABLED, /*!< Device is enabled - reset by the host */ + LDD_USB_DEVICE_SUSPENDED = ERR_USB_DEVICE_SUSPENDED, /*!< Device is suspended - Bus is idle more then 3 ms */ + LDD_USB_DEVICE_SUSPENDED_RESUME_READY = ERR_USB_DEVICE_SUSPENDED_RESUME_READY, /*!< Device can generate resume signaling - Bus is idle more then 5 ms. */ + LDD_USB_DEVICE_RESUME_PENDING = ERR_USB_DEVICE_RESUME_PENDING /*!< Device generates resume signaling */ +} LDD_USB_Device_TState; + +/*! USB host mode states symbolic names */ +typedef enum { + LDD_USB_HOST_DISABLED = ERR_USB_HOST_DISABLED, /*!< Host mode is disabled (by the user or by the clock configuration) */ + LDD_USB_HOST_DISABLED_BY_OTG = ERR_USB_HOST_DISABLED_BY_OTG, /*!< Host mode is disabled by the OTG driver */ + LDD_USB_HOST_PORT_POWERED_OFF = ERR_USB_HOST_PORT_POWERED_OFF, /*!< Port is powered-off */ + LDD_USB_HOST_PORT_DISCONNECTED = ERR_USB_HOST_PORT_DISCONNECTED, /*!< No device is connected */ + LDD_USB_HOST_PORT_DISABLED = ERR_USB_HOST_PORT_DISABLED, /*!< Device is connected to the port */ + LDD_USB_HOST_PORT_RESETING = ERR_USB_HOST_PORT_RESETING, /*!< Port generates reset signaling */ + LDD_USB_HOST_PORT_RESET_RECOVERING = ERR_USB_HOST_PORT_RESET_RECOVERING, /*!< Port waits 10 ms for reset recovery */ + LDD_USB_HOST_PORT_ENABLED = ERR_USB_HOST_PORT_ENABLED, /*!< Device is connected, reset and ready to use */ + LDD_USB_HOST_PORT_SUSPENDED = ERR_USB_HOST_PORT_SUSPENDED, /*!< Port is suspended */ + LDD_USB_HOST_PORT_RESUME_READY = ERR_USB_HOST_PORT_RESUME_READY, /*!< Port is ready to generate resume signaling */ + LDD_USB_HOST_PORT_RESUMING = ERR_USB_HOST_PORT_RESUMING, /*!< Port generates resume signaling */ + LDD_USB_HOST_PORT_RESUME_RECOVERING = ERR_USB_HOST_PORT_RESUME_RECOVERING /*!< Port waits 10 ms for resume recovery */ +} LDD_USB_Host_TState; + +/*! USB otg mode states symbolic names */ +typedef enum { + LDD_USB_OTG_DISABLED = ERR_USB_OTG_DISABLED, /*!< OTG device is in DISABLED state */ + LDD_USB_OTG_ENABLED = ERR_USB_OTG_ENABLED_PENDING, /*!< OTG device is in ENABLED_PENDING state */ + LDD_USB_OTG_A_IDLE = ERR_USB_OTG_A_IDLE, /*!< OTG device is in A_IDLE state */ + LDD_USB_OTG_A_WAIT_VRISE = ERR_USB_OTG_A_WAIT_VRISE, /*!< OTG device is in A_WAIT_VRISE state */ + LDD_USB_OTG_A_WAIT_VFALL = ERR_USB_OTG_A_WAIT_VFALL, /*!< OTG device is in A_WAIT_VFALL state */ + LDD_USB_OTG_A_WAIT_BCON = ERR_USB_OTG_A_WAIT_BCON, /*!< OTG device is in A_WAIT_BCON state */ + LDD_USB_OTG_A_VBUS_ERROR = ERR_USB_OTG_A_VBUS_ERROR, /*!< OTG device is in A_VBUS_ERROR state */ + LDD_USB_OTG_A_SUSPEND = ERR_USB_OTG_A_SUSPEND, /*!< OTG device is in A_SUSPEND state */ + LDD_USB_OTG_B_IDLE = ERR_USB_OTG_B_IDLE, /*!< OTG device is in B_IDLE state */ + LDD_USB_OTG_B_SRP_INIT = ERR_USB_OTG_B_SRP_INIT, /*!< OTG device is in B_SRP_INIT state */ + LDD_USB_OTG_B_WAIT_ACON = ERR_USB_OTG_B_WAIT_ACON, /*!< OTG device is in B_WAIT_ACON state */ + LDD_USB_OTG_A_HOST = ERR_USB_OTG_A_HOST, /*!< OTG device is in A_HOST state */ + LDD_USB_OTG_A_PERIPHERAL = ERR_USB_OTG_A_PERIPHERAL, /*!< OTG device is in A_PERIPHERAL state */ + LDD_USB_OTG_B_HOST = ERR_USB_OTG_B_HOST, /*!< OTG device is in B_HOST state */ + LDD_USB_OTG_B_PERIPHERAL = ERR_USB_OTG_B_PERIPHERAL /*!< OTG device is in B_PERIPHERAL state */ +} LDD_USB_Otg_TState; + +/*! USB Otg commands symbolic names */ +typedef enum { + LDD_USB_OTG_CMD_SET_A_BUS_REQUEST, /*!< A-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_REQUEST, /*!< A-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_B_BUS_REQUEST, /*!< B-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_B_BUS_REQUEST, /*!< B-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_A_BUS_DROP, /*!< A-device application needs to power down the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_DROP, /*!< A-device application doesn't need to power down the bus */ + LDD_USB_OTG_CMD_SET_A_SUSPEND_REQUEST, /*!< A-device application wants to suspend the bus */ + LDD_USB_OTG_CMD_CLR_A_SUSPEND_REQUEST, /*!< A-device application doesn't want to suspend the bus */ + LDD_USB_OTG_CMD_SET_A_SET_B_HNP_EN_REQUEST, /*!< A-device sets HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_CLR_A_SET_B_HNP_EN_REQUEST, /*!< A-device clears HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_SET_B_HNP_EN_REQUEST, /*!< Enable B-device HNP */ + LDD_USB_OTG_CMD_CLR_B_HNP_EN_REQUEST /*!< Disable B-device HNP */ +} LDD_USB_Otg_TCmd; + +/*! USB host port control commands symbolic names */ +typedef enum { + LDD_USB_HOST_PORT_CMD_POWER_ON, /*!< Power-on the bus */ + LDD_USB_HOST_PORT_CMD_POWER_OFF, /*!< Power-off the bus */ + LDD_USB_HOST_PORT_CMD_RESET, /*!< Perform the bus reset signaling and call event after the reset recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_RESUME, /*!< Perform the bus resume signaling and call event after the resume recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_SUSPEND, /*!< Suspend the bus and transceiver */ + LDD_USB_HOST_PORT_CMD_DISABLE /*!< Disable the port */ +} LDD_USB_Host_TPortControlCmd; + +/*! USB host handle prototypes */ +typedef void LDD_USB_Host_TPipeHandle; /*!< Pipe handle prototype */ +typedef void LDD_USB_Host_TTransferHandle; /*!< Transfer handle prototype */ + +/*! USB host pipe descriptor structure */ +typedef struct LDD_USB_Host_TPipeDescr_Struct { + uint8_t DevAddress; /*!< Device address */ + LDD_USB_TBusSpeed DevSpeed; /*!< Device speed */ + uint8_t EpNumber; /*!< EP number */ + uint8_t EpDir; /*!< EP direction */ + LDD_USB_TTransferType TransferType; /*!< EP Transfer type */ + uint16_t MaxPacketSize; /*!< EP max. packet size */ + uint8_t TrPerUFrame; /*!< Transaction pre microframe */ + uint32_t Interval; /*!< Interval for polling endpoint for data transfers */ + uint32_t NAKCount; /*!< NAK count */ + uint8_t Flags; /*!< 1 = ZLT */ +} LDD_USB_Host_TPipeDescr; + +/*! USB host transfer done callback prototype */ +typedef void (LDD_USB_Host_TTransferDoneCalback)( + LDD_TDeviceData *DevDataPtr, /*!< User value passed as parameter of the Init() method */ + LDD_TData *BufferPtr, /*!< Buffer address */ + uint16_t BufferSize, /*!< Transferred data size */ + uint8_t *ParamPtr, /*!< User value passed in Send()/Recv() method */ + LDD_USB_TTransferState Status /*!< Transfer status */ +); + +/*! USB host transfer descriptor structure */ +typedef struct LDD_USB_Host_TTD_Struct { + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags */ + LDD_USB_Host_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ + LDD_USB_TSDP *SDPPrt; /*!< Setup data buffer pointer */ +} LDD_USB_Host_TTD; + +/*! Following USB constants and types are for test purpose only */ + +/* Request types */ +#define LDD_USB_REQ_TYPE_STANDARD 0x00u /*!< Standard request */ +#define LDD_USB_REQ_TYPE_CLASS 0x20u /*!< Class request */ +#define LDD_USB_REQ_TYPE_VENDOR 0x40u /*!< Vendor request */ +#define LDD_USB_REQ_TYPE_MASK 0x60u /*!< Bit mask for request type (bmRequestType) */ + +/* Request recepient */ +#define LDD_USB_REQ_RECP_DEVICE 0x00u /*!< Recipient = Device */ +#define LDD_USB_REQ_RECP_INTERFACE 0x01u /*!< Recipient = Interface */ +#define LDD_USB_REQ_RECP_ENDPOINT 0x02u /*!< Recipient = Endpoint */ +#define LDD_USB_REQ_RECP_OTHER 0x03u /*!< Recipient = Other */ +#define LDD_USB_REQ_RECP_MASK 0x03u /*!< Bit mask for recipient */ + +/* Standard request codes (bRequest) */ +#define LDD_USB_REQ_GET_STATUS 0x00u /*!< GET_STATUS request code */ +#define LDD_USB_REQ_CLEAR_FEATURE 0x01u /*!< CLEAR_FEATURE request code */ +#define LDD_USB_REQ_SET_FEATURE 0x03u /*!< SET_FEATURE request code */ +#define LDD_USB_REQ_GET_STATE 0x04u /*!< GET_STATE request code (for Hub Class only)*/ +#define LDD_USB_REQ_SET_ADDRESS 0x05u /*!< SET_ADDRESS request code */ +#define LDD_USB_REQ_GET_DESCRIPTOR 0x06u /*!< GET_DESCRIPTOR request code */ +#define LDD_USB_REQ_SET_DESCRIPTOR 0x07u /*!< SET_DESCRIPTOR request code, this request is not supported */ +#define LDD_USB_REQ_GET_CONFIGURATION 0x08u /*!< GET_CONFIGURATION request code */ +#define LDD_USB_REQ_SET_CONFIGURATION 0x09u /*!< SET_CONFIGURATION request code */ +#define LDD_USB_REQ_GET_INTERFACE 0x0Au /*!< GET_INTERFACE request code */ +#define LDD_USB_REQ_SET_INTERFACE 0x0Bu /*!< SET_INTERFACE request code */ +#define LDD_USB_REQ_SYNCH_FRAME 0x0Cu /*!< SYNCH_FRAME request code */ + +/* Standard request words for device (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_DEV_STATUS 0x0080u /*!< GET_DEVICE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_DEV_FEATURE 0x0100u /*!< CLEAR_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DEV_FEATURE 0x0300u /*!< SET_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_ADDRESS 0x0500u /*!< SET_DEVICE_ADDRESS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_DESCRIPTOR 0x0680u /*!< GET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DESCRIPTOR 0x0700u /*!< SET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_CONFIGURATION 0x0880u /*!< GET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_CONFIGURATION 0x0900u /*!< SET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ + +/* Standard request words for interface (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_INT_STATUS 0x0081u /*!< GET_INTERFACE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_INT_FEATURE 0x0101u /*!< CLEAR_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INT_FEATURE 0x0301u /*!< SET_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_INTERFACE 0x0A81u /*!< GET_DEVICE_INTERFACE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INTERFACE 0x0B01u /*!< SET_DEVICE_INTERFACE bmRequestType and bRequest word */ + +/* Standard request words for endpoint (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_EP_STATUS 0x0082u /*!< GET_ENDPOINT_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_EP_FEATURE 0x0102u /*!< CLEAR_ENDPOINT_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_EP_FEATURE 0x0302u /*!< ENDPOINT_ bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SYNCH_FRAME 0x0C12u /*!< SYNCH_DEVICE_FRAME bmRequestType and bRequest code */ + +#define LDD_USB_STATUS_DEVICE_SELF_POWERED_MASK 0x01u +#define LDD_USB_STATUS_DEVICE_REMOTE_WAKEUP_MASK 0x02u + +/* Standard descriptors */ +#define LDD_USB_DT_DEVICE 0x01u /*!< Device descriptor */ +#define LDD_USB_DT_CONFIGURATION 0x02u /*!< Configuration descriptor */ +#define LDD_USB_DT_STRING 0x03u /*!< String descriptor */ +#define LDD_USB_DT_INTERFACE 0x04u /*!< Interface descriptor */ +#define LDD_USB_DT_ENDPOINT 0x05u /*!< Endpoint descriptor */ +#define LDD_USB_DT_DEVICE_QUALIFIER 0x06u /*!< Device qualifier descriptor */ +#define LDD_USB_DT_OTHER_SPEED_CONFIGURATION 0x07u /*!< Other speed configuration descriptor */ +#define LDD_USB_DT_INTERFACE_POWER 0x08u /*!< Interface-level power management descriptor */ +#define LDD_USB_DT_OTG 0x09u /*!< OTG descriptor */ +#define LDD_USB_DT_DEBUG 0x0Au /*!< Debug descriptor */ +#define LDD_USB_DT_INTERFACE_ASSOCIATION 0x0Bu /*!< Interface association descriptor */ + +/* Standard feature selectors */ +#define LDD_USB_FEATURE_EP_HALT 0x00u /*!< Endpoint HALT feature selector */ +#define LDD_USB_FEATURE_DEV_REMOTE_WAKEUP 0x01u /*!< Remote Wake-up feature selector */ +#define LDD_USB_FEATURE_DEV_TEST_MODE 0x02u /*!< Test mode feature selector */ + +/*! Get decriptor request structure */ +typedef struct LDD_USB_TGetDecriptorRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bDescriptorIndex; /*!< Descriptor index */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t wLanguageID; /*!< Language ID */ + uint16_t wLength; /*!< Requested data size */ +} LDD_USB_TGetDecriptorRequest; + +/*! Get endpoint status request structure */ +typedef struct LDD_USB_TEndpointStatusRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wValue; /*!< Not used, should be set to zero */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Reqested data size, should be set to 2 */ +} LDD_USB_TEndpointStatusRequest; + +/*! Clear/Set endpoint feature request structure */ +typedef struct LDD_USB_TEndpointFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TEndpointFeatureRequest; + +/*! Clear/Set interface request structure */ +typedef struct LDD_USB_TInterfaceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TInterfaceFeatureRequest; + +/*! Clear/Set device request structure */ +typedef struct LDD_USB_TDeviceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TDeviceFeatureRequest; + +/*! Get interface request structure */ +typedef struct LDD_USB_TGetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wWalue; /*!< Not used, should be zero */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Reqested data size, should be set to 1 */ +} LDD_USB_TGetInterfaceRequest; + +/*! Set interface request structure */ +typedef struct LDD_USB_TSetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wAltSet; /*!< Alternate setting */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetInterfaceRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetAddressRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t DeviceAddress; /*!< Device address */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetAddressRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetConfigRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint8_t ConfigNumber; /*!< Configuration number */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetConfigRequest; + +/* +** =================================================================== +** DAC device types and constants +** =================================================================== +*/ +#define LDD_DAC_OUTPUT_PIN_0 0x01u /*!< DAC output pin 0 mask */ + +#define LDD_DAC_ON_BUFFER_END 0x01U /*!< OnBufferEnd event mask */ +#define LDD_DAC_ON_BUFFER_START 0x02U /*!< OnBufferStart event mask */ +#define LDD_DAC_ON_BUFFER_WATERMARK 0x04U /*!< OnBufferWatermark event mask */ +#define LDD_DAC_ON_COMPLETE LDD_DMA_ON_COMPLETE /*!< OnComplete event mask */ +#define LDD_DAC_ON_ERROR LDD_DMA_ON_ERROR /*!< OnError event mask */ + +/*! Type specifying the DAC buffer work mode */ +typedef enum { + LDD_DAC_BUFFER_NORMAL_MODE = 0x00U, /*!< Normal (cyclic) mode */ + LDD_DAC_BUFFER_SWING_MODE = 0x01U, /*!< Swing mode */ + LDD_DAC_BUFFER_SCAN_MODE = 0x02U /*!< One-time scan mode */ +} LDD_DAC_TBufferMode; + +/*! Type specifying the DAC buffer watermark levels */ +typedef enum { + LDD_DAC_BUFFER_WATERMARK_L1 = 0x00U, + LDD_DAC_BUFFER_WATERMARK_L2 = 0x01U, + LDD_DAC_BUFFER_WATERMARK_L3 = 0x02U, + LDD_DAC_BUFFER_WATERMARK_L4 = 0x03U +} LDD_DAC_TBufferWatermark; + +#define LDD_DAC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef void* LDD_DAC_TDataPtr; /*!< Type specifying the pointer to the DAC data variable */ +typedef uint32_t LDD_DAC_TData; /*!< The DAC data variable type */ +typedef uint32_t LDD_DAC_TErrorMask; /*!< Error mask */ +typedef uint32_t LDD_DAC_TArrayLength; /*!< Array length type */ + +/* +** =================================================================== +** FLASH device types and constants +** =================================================================== +*/ +#define LDD_FLASH_ON_OPERATION_COMPLETE 0x02u /*!< OnOperationComplete event mask */ +#define LDD_FLASH_ON_ERROR 0x04u /*!< OnError event mask */ + +#define LDD_FLASH_READ_COLLISION_ERROR 0x40u /*!< Read collision error flag's mask */ +#define LDD_FLASH_ACCESS_ERROR 0x20u /*!< Access error flag's mask */ +#define LDD_FLASH_PROTECTION_VIOLATION 0x10u /*!< Protection violation error flag's mask */ +#define LDD_FLASH_ERASE_VERIFICATION_ERROR 0x08u /*!< Erase verification error flag's mask */ +#define LDD_FLASH_MULTIPLE_WRITE_ERROR 0x04u /*!< Multiple write to one flash memory location error flag's mask */ + +/*! Type specifying HW commands for a flash device */ +typedef enum { + LDD_FLASH_READ_1S_BLOCK = 0x00u, /*!< Checks if an entire program flash or data flash logical block has been erased to the specified margin level */ + LDD_FLASH_READ_1S_SECTION = 0x01u, /*!< Checks if a section of program flash or data flash memory is erased to the specified read margin level */ + LDD_FLASH_WRITE_BYTE = 0x04u, /*!< Program byte */ + LDD_FLASH_WRITE_WORD = 0x05u, /*!< Program word */ + LDD_FLASH_WRITE_LONG_WORD = 0x06u, /*!< Program long word */ + LDD_FLASH_WRITE_PHRASE = 0x07u, /*!< Program phrase */ + LDD_FLASH_ERASE_FLASH_BLOCK = 0x08u, /*!< Erase flash memory block */ + LDD_FLASH_ERASE_SECTOR = 0x09u, /*!< Erase sector */ + LDD_FLASH_ERASE_ALL_FLASH_BLOCKS = 0x44u /*!< Erase all flash memory blocks */ +} LDD_FLASH_TCommand; + +/*! Type specifying possible FLASH component operation types */ +typedef enum { + LDD_FLASH_NO_OPERATION, /*!< No operation - initial state */ + LDD_FLASH_READ, /*!< Read operation */ + LDD_FLASH_WRITE, /*!< Write operation */ + LDD_FLASH_ERASE, /*!< Erase operation */ + LDD_FLASH_ERASE_BLOCK, /*!< Erase block operation */ + LDD_FLASH_VERIFY_ERASED_BLOCK /*!< Verify erased block operation */ +} LDD_FLASH_TOperationType; + +/*! Type specifying possible FLASH component operation states */ +typedef enum { + LDD_FLASH_FAILED = 0x00u, /*!< Operation has failed */ + LDD_FLASH_STOP = 0x01u, /*!< The operation has been stopped */ + LDD_FLASH_IDLE = 0x02u, /*!< No operation in progress */ + LDD_FLASH_STOP_REQ = 0x03u, /*!< The operation is in the STOP request mode */ + LDD_FLASH_START = 0x04u, /*!< Start of the operation, no operation steps have been done yet */ + LDD_FLASH_RUNNING = 0x05u /*!< Operation is in progress */ +} LDD_FLASH_TOperationStatus; + +typedef uint8_t LDD_FLASH_TErrorFlags; /*!< Type specifying FLASH component's error flags bit field */ + +typedef uint32_t LDD_FLASH_TAddress; /*!< Type specifying the Address parameter used by the FLASH component's methods */ + +typedef uint32_t LDD_FLASH_TDataSize; /*!< Type specifying the Size parameter used by the FLASH component's methods */ + +typedef uint16_t LDD_FLASH_TErasableUnitSize; /*!< Type specifying the Size output parameter of the GetErasableUnitSize method (pointer to a variable of this type is passed to the method) */ + +/*! Type specifying the FLASH component's rrror status information */ +typedef struct { + LDD_FLASH_TOperationType CurrentOperation; /*!< Current operation */ + LDD_FLASH_TCommand CurrentCommand; /*!< Last flash controller command */ + LDD_FLASH_TErrorFlags CurrentErrorFlags; /*!< Bitfield with error flags. See FLASH2.h for details */ + LDD_FLASH_TAddress CurrentAddress; /*!< Address of the flash memory location the error status is related to */ + LDD_TData *CurrentDataPtr; /*!< Pointer to current input data the error status is related to */ + LDD_FLASH_TDataSize CurrentDataSize; /*!< Size of the current input data to be programmed or erased in bytes */ +} LDD_FLASH_TErrorStatus; + +/* +** =================================================================== +** HSCMP device types and constants +** =================================================================== +*/ + +#define LDD_ANALOGCOMP_ON_COMPARE 0x01u /*!< OnCompare event mask */ + +/* Positive input pin masks */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_0_MASK 0x01U /*!< Mask for positive input pin 0 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_1_MASK 0x02U /*!< Mask for positive input pin 1 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_2_MASK 0x04U /*!< Mask for positive input pin 2 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_3_MASK 0x08U /*!< Mask for positive input pin 3 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_4_MASK 0x10U /*!< Mask for positive input pin 4 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_5_MASK 0x20U /*!< Mask for positive input pin 5 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_6_MASK 0x40U /*!< Mask for positive input pin 6 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_7_MASK 0x80U /*!< Mask for positive input pin 7 */ + +/* Negative input pin masks */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_0_MASK 0x0100U /*!< Mask for negative input pin 0 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_1_MASK 0x0200U /*!< Mask for negative input pin 1 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_2_MASK 0x0400U /*!< Mask for negative input pin 2 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_3_MASK 0x0800U /*!< Mask for negative input pin 3 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_4_MASK 0x1000U /*!< Mask for negative input pin 4 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_5_MASK 0x2000U /*!< Mask for negative input pin 5 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_6_MASK 0x4000U /*!< Mask for negative input pin 6 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_7_MASK 0x8000U /*!< Mask for negative input pin 7 */ + +/* Output pin masks */ +#define LDD_ANALOGCOMP_OUTPUT_PIN_MASK 0x00010000U /*!< Mask for output pin */ + +/* Window Sample pin masks */ +#define LDD_ANALOGCOMP_WINDOWSAMPLE_PIN_MASK 0x00020000UL + +/*! Type specifying comparator input number */ +typedef enum { + LDD_ANALOGCOMP_INPUT_0 = 0x00U, /*!< Analog input 0 selected */ + LDD_ANALOGCOMP_INPUT_1 = 0x01U, /*!< Analog input 1 selected */ + LDD_ANALOGCOMP_INPUT_2 = 0x02U, /*!< Analog input 2 selected */ + LDD_ANALOGCOMP_INPUT_3 = 0x03U, /*!< Analog input 3 selected */ + LDD_ANALOGCOMP_INPUT_4 = 0x04U, /*!< Analog input 4 selected */ + LDD_ANALOGCOMP_INPUT_5 = 0x05U, /*!< Analog input 5 selected */ + LDD_ANALOGCOMP_INPUT_6 = 0x06U, /*!< Analog input 6 selected */ + LDD_ANALOGCOMP_INPUT_7 = 0x07U, /*!< Analog input 7 selected */ + LDD_ANALOGCOMP_INPUT_DISABLED = 0x08U /*!< Analog input disabled */ +} LDD_AnalogComp_TComparatorInput; + +/*! Type specifying current comparator output status */ +typedef enum { + LDD_ANALOGCOMP_NO_EDGE = 0x00U, /*!< No edge detected on output */ + LDD_ANALOGCOMP_FALLING_EDGE = 0x02U, /*!< Falling edge detected on output */ + LDD_ANALOGCOMP_RISING_EDGE = 0x04U, /*!< Rising edge detected on output */ + LDD_ANALOGCOMP_BOTH_EDGES = 0x06U /*!< Both edges detected on output */ +} LDD_AnalogComp_TCompareStatus; + +/*! Type specifying requested comparator mode */ +typedef enum { + LDD_ANALOGCOMP_RISING_EDGE_MODE = 0x10U, /*!< Rising edge detection */ + LDD_ANALOGCOMP_FALLING_EDGE_MODE = 0x08U, /*!< Falling edge detection */ + LDD_ANALOGCOMP_BOTH_EDGES_MODE = 0x18U /*!< Both edges detection */ +} LDD_AnalogComp_TComparatorMode; + +typedef uint8_t LDD_AnalogComp_TOutputValue; /*!< Type specifying comparator output value */ + +/* +** =================================================================== +** SDHC component types and constants +** =================================================================== +*/ + +#define LDD_SDHC_CARD_DATA_WIDTH_1_BIT 0x01u /*!< Card supports 1 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_4_BIT 0x02u /*!< Card supports 4 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_8_BIT 0x04u /*!< Card supports 8 bit data bus */ +#define LDD_SDHC_CARD_BLOCK_READ 0x01u /*!< Card supports block reading */ +#define LDD_SDHC_CARD_BLOCK_WRITE 0x04u /*!< Card supports block writing */ +#define LDD_SDHC_CARD_ERASE 0x08u /*!< Card supports block erasion */ +#define LDD_SDHC_CARD_WRITE_PROTECTION 0x10u /*!< Card supports write protection */ +#define LDD_SDHC_CARD_IO 0x80u /*!< Card supports IO */ + +#define LDD_SDHC_CLK_PIN 0x01u /*!< SD clock pin mask */ +#define LDD_SDHC_CMD_PIN 0x02u /*!< SD command line pin mask */ +#define LDD_SDHC_DAT0_PIN 0x04u /*!< SD data line 0 pin mask */ +#define LDD_SDHC_DAT1_PIN 0x08u /*!< SD data line 1 pin mask */ +#define LDD_SDHC_DAT2_PIN 0x10u /*!< SD data line 2 pin mask */ +#define LDD_SDHC_DAT3_PIN 0x20u /*!< SD data line 3 pin mask */ +#define LDD_SDHC_DAT4_PIN 0x40u /*!< SD data line 4 pin mask */ +#define LDD_SDHC_DAT5_PIN 0x80u /*!< SD data line 5 pin mask */ +#define LDD_SDHC_DAT6_PIN 0x0100u /*!< SD data line 6 pin mask */ +#define LDD_SDHC_DAT7_PIN 0x0200u /*!< SD data line 7 pin mask */ +#define LDD_SDHC_CD_PIN 0x0400u /*!< SD card detection pin mask */ +#define LDD_SDHC_WP_PIN 0x0800u /*!< SD write protection pin mask */ +#define LDD_SDHC_LCTL_PIN 0x1000u /*!< SD LED control pin mask */ +#define LDD_SDHC_VS_PIN 0x2000u /*!< SD voltage control pin mask */ + +#define LDD_SDHC_ON_CARD_INSERTED 0x01u /*!< OnCardInserted event mask */ +#define LDD_SDHC_ON_CARD_REMOVED 0x02u /*!< OnCardRemoved event mask */ +#define LDD_SDHC_ON_FINISHED 0x04u /*!< OnFinished event mask */ + +/*! Card types */ +typedef enum { + LDD_SDHC_SD, /*!< Secure Digital memory card */ + LDD_SDHC_SDIO, /*!< Secure Digital IO card */ + LDD_SDHC_SDCOMBO, /*!< Combined Secure Digital memory and IO card */ + LDD_SDHC_MMC, /*!< MultiMediaCard memory card */ + LDD_SDHC_CE_ATA /*!< Consumer Electronics ATA card */ +} LDD_SDHC_TCardType; + +/*! Card access properties */ +typedef struct { + uint16_t MaxBlockLength; /*!< Max. transferable block length */ + bool MisalignBlock; /*!< Indicates if the data block can be spread over more than one physical block of the memory device */ + bool PartialBlock; /*!< Indicates whether partial block sizes can be used in block access */ +} LDD_SDHC_TCardAccess; + +/*! Card erasion properties */ +typedef struct { + uint16_t SectorSize; /*!< The size of an erasable unit */ + uint8_t Pattern; /*!< Memory content after erase */ +} LDD_SDHC_TCardErase; + +/*! Card write protection properties */ +typedef struct { + uint16_t GroupSize; /*!< The size of write protected group in number of erase groups */ + bool Permanent; /*!< Indicates whether card is permanently write protected (read-only) */ +} LDD_SDHC_TCardWriteProtect; + +/*! Card capabilities */ +typedef struct { + uint8_t DataWidths; /*!< Bit mask of supported data bus widths */ + uint8_t Operations; /*!< Bit mask of supported operations */ + bool HighSpeed; /*!< Indicates whether the card supports high clock configuration (SD bus clock frequency higher than about 25MHz) */ + bool HighCapacity; /*!< Indicates whether the card requires block addressing instead of byte addressing */ + bool LowVoltage; /*!< Indicates whether the card supports the host's low voltage range */ + LDD_SDHC_TCardAccess Read; /*!< Card data read access capabilities */ + LDD_SDHC_TCardAccess Write; /*!< Card data write access capabilities */ + LDD_SDHC_TCardErase Erase; /*!< Card data erasion capabilities */ + LDD_SDHC_TCardWriteProtect WriteProtect; /*!< Write protection properties */ +} LDD_SDHC_TCardCaps; + +/*! Card features description */ +typedef struct { + LDD_SDHC_TCardType Type; /*!< Card type */ + uint16_t BlockLength; /*!< Physical memory block length */ + uint32_t BlockCount; /*!< Number of physical memory blocks */ + LDD_SDHC_TCardCaps Caps; /*!< Card capabilities */ +} LDD_SDHC_TCardInfo; + +/*! Transfer operations */ +typedef enum { + LDD_SDHC_READ, /*!< Read operation */ + LDD_SDHC_WRITE /*!< Write operation */ +} LDD_SDHC_TTransferOperation; + +/*! Transfer buffer descriptor */ +typedef struct { + uint16_t Size; /*!< Buffer data size */ + uint8_t *DataPtr; /*!< Pointer to buffer data */ +} LDD_SDHC_TBufferDesc; + +/*! Voltage options */ +typedef enum { + LDD_SDHC_LOW_VOLTAGE, /*!< Low voltage */ + LDD_SDHC_HIGH_VOLTAGE /*!< High voltage */ +} LDD_SDHC_TVoltage; + +/*! Write protection types */ +typedef enum { + LDD_SDHC_GROUP, /*!< Write protection by groups */ + LDD_SDHC_CARD /*!< Whole card write protection */ +} LDD_SDHC_TWriteProtectType; + +/*! Component states */ +typedef enum { + LDD_SDHC_DISABLED, /*!< Disabled */ + LDD_SDHC_RESET, /*!< Resetting card */ + LDD_SDHC_IDLE, /*!< Idling */ + LDD_SDHC_VOLTAGE_VALIDATION, /*!< Validating voltage */ + LDD_SDHC_CARD_REGISTRATION, /*!< Registrating card */ + LDD_SDHC_CARD_SELECTION, /*!< Selecting card */ + LDD_SDHC_CARD_INFO_RETRIEVAL, /*!< Retrieving card info */ + LDD_SDHC_TRANSFER, /*!< Transferring data */ + LDD_SDHC_ERASION, /*!< Erasing blocks */ + LDD_SDHC_IO_REG_TRANSFER, /*!< Transferring IO registers */ + LDD_SDHC_DATA_WIDTH_SELECTION, /*!< Selecting data width */ + LDD_SDHC_BUS_CLOCK_SELECTION, /*!< Selecting bus clock */ + LDD_SDHC_WRITE_PROTECTION_SETUP, /*!< Setting up write protection */ + LDD_SDHC_WRITE_PROTECTION_RETRIEVAL /*!< Retrieving write protection configuration */ +} LDD_SDHC_TStatus; + +/*! Operation completion error codes */ +typedef enum { + LDD_SDHC_ERR_OK, /*!< No error */ + LDD_SDHC_ERR_DMA, /*!< DMA or block size error */ + LDD_SDHC_ERR_NOT_SUPPORTED, /*!< Initiated operation is not supported by the card (supported operations are contained in the card information structure) */ + LDD_SDHC_ERR_TIMEOUT, /*!< Command or data timeout */ + LDD_SDHC_ERR_COMMAND_CRC, /*!< Command CRC check failed */ + LDD_SDHC_ERR_DATA_CRC, /*!< Data CRC check failed */ + LDD_SDHC_ERR_ADDRESS_OUT_OF_RANGE, /*!< The card address is beyond the card capacity */ + LDD_SDHC_ERR_ADDRESS_MISALIGN, /*!< The card address does not align with physical blocks of the card */ + LDD_SDHC_ERR_BLOCK_LEN_ERROR, /*!< Block length exceeds the maximum value for the card */ + LDD_SDHC_ERR_WP_VIOLATION, /*!< Attempt to program a write protected block */ + LDD_SDHC_ERR_CARD_IS_LOCKED, /*!< The card is locked by the host */ + LDD_SDHC_ERR_WP_ERASE_SKIP, /*!< Only partial address space was erased due to existing write protected blocks */ + LDD_SDHC_ERR_INTERNAL_FAILURE, /*!< Internal component error */ + LDD_SDHC_ERR_CARD_FAILURE /*!< The card was unable to complete the operation */ +} LDD_SDHC_TError; + +/* +** =================================================================== +** DMA device types and constants +** =================================================================== +*/ + +#define LDD_DMA_ON_COMPLETE 0x01U /*!< OnTransferComplete event mask. */ +#define LDD_DMA_ON_ERROR 0x02U /*!< OnError event mask. */ + +#define LDD_DMA_UNKNOWN_ERROR 0x80000000U /*!< Unknown error. */ +#define LDD_DMA_CHANNEL_PRIORITY_ERROR 0x4000U /*!< Channel priority error. */ +#define LDD_DMA_SOURCE_ADDRESS_ERROR 0x80U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_SOURCE_OFFSET_ERROR 0x40U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_ADDRESS_ERROR 0x20U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_OFFSET_ERROR 0x10U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_COUNT_ERROR 0x08U /*!< Byte count inconsistency with transfer sizes or transfer count error. */ +#define LDD_DMA_SCATTER_GATHER_ERROR 0x04U /*!< Scatter/gather configuration error. */ +#define LDD_DMA_SOURCE_BUS_ERROR 0x02U /*!< Bus error on a source read. */ +#define LDD_DMA_DESTINATION_BUS_ERROR 0x01U /*!< Bus error on a destination write. */ + +#define LDD_DMA_CHANNEL_0_MASK 0x01UL /*!< DMA channel 0 mask. */ +#define LDD_DMA_CHANNEL_1_MASK 0x02UL /*!< DMA channel 1 mask. */ +#define LDD_DMA_CHANNEL_2_MASK 0x04UL /*!< DMA channel 2 mask. */ +#define LDD_DMA_CHANNEL_3_MASK 0x08UL /*!< DMA channel 3 mask. */ +#define LDD_DMA_CHANNEL_4_MASK 0x10UL /*!< DMA channel 4 mask. */ +#define LDD_DMA_CHANNEL_5_MASK 0x20UL /*!< DMA channel 5 mask. */ +#define LDD_DMA_CHANNEL_6_MASK 0x40UL /*!< DMA channel 6 mask. */ +#define LDD_DMA_CHANNEL_7_MASK 0x80UL /*!< DMA channel 7 mask. */ +#define LDD_DMA_CHANNEL_8_MASK 0x0100UL /*!< DMA channel 8 mask. */ +#define LDD_DMA_CHANNEL_9_MASK 0x0200UL /*!< DMA channel 9 mask. */ +#define LDD_DMA_CHANNEL_10_MASK 0x0400UL /*!< DMA channel 10 mask. */ +#define LDD_DMA_CHANNEL_11_MASK 0x0800UL /*!< DMA channel 11 mask. */ +#define LDD_DMA_CHANNEL_12_MASK 0x1000UL /*!< DMA channel 12 mask. */ +#define LDD_DMA_CHANNEL_13_MASK 0x2000UL /*!< DMA channel 13 mask. */ +#define LDD_DMA_CHANNEL_14_MASK 0x4000UL /*!< DMA channel 14 mask. */ +#define LDD_DMA_CHANNEL_15_MASK 0x8000UL /*!< DMA channel 15 mask. */ +#define LDD_DMA_CHANNEL_16_MASK 0x00010000UL /*!< DMA channel 16 mask. */ +#define LDD_DMA_CHANNEL_17_MASK 0x00020000UL /*!< DMA channel 17 mask. */ +#define LDD_DMA_CHANNEL_18_MASK 0x00040000UL /*!< DMA channel 18 mask. */ +#define LDD_DMA_CHANNEL_19_MASK 0x00080000UL /*!< DMA channel 19 mask. */ +#define LDD_DMA_CHANNEL_20_MASK 0x00100000UL /*!< DMA channel 21 mask. */ +#define LDD_DMA_CHANNEL_21_MASK 0x00200000UL /*!< DMA channel 22 mask. */ +#define LDD_DMA_CHANNEL_22_MASK 0x00400000UL /*!< DMA channel 23 mask. */ +#define LDD_DMA_CHANNEL_23_MASK 0x00800000UL /*!< DMA channel 24 mask. */ +#define LDD_DMA_CHANNEL_24_MASK 0x01000000UL /*!< DMA channel 25 mask. */ +#define LDD_DMA_CHANNEL_25_MASK 0x02000000UL /*!< DMA channel 26 mask. */ +#define LDD_DMA_CHANNEL_26_MASK 0x04000000UL /*!< DMA channel 27 mask. */ +#define LDD_DMA_CHANNEL_27_MASK 0x08000000UL /*!< DMA channel 28 mask. */ +#define LDD_DMA_CHANNEL_28_MASK 0x10000000UL /*!< DMA channel 29 mask. */ +#define LDD_DMA_CHANNEL_29_MASK 0x20000000UL /*!< DMA channel 30 mask. */ +#define LDD_DMA_CHANNEL_30_MASK 0x40000000UL /*!< DMA channel 31 mask. */ +#define LDD_DMA_CHANNEL_31_MASK 0x80000000UL /*!< DMA channel 32 mask. */ + +/* Action executed after request and transfer service completes */ +#define LDD_DMA_NO_ACTION 0x00U /*!< No action performed after request serviced. */ +#define LDD_DMA_DESTINATION_ADDRESS_ADJUSTMENT 0x01U /*!< Destination address adjustment after request serviced. */ +#define LDD_DMA_SOURCE_ADDRESS_ADJUSTMENT 0x02U /*!< Source address adjustment after request serviced. */ +#define LDD_DMA_ADDRESS_ADJUSTMENT 0x01U /*!< Address adjustment after transfer completed. */ +#define LDD_DMA_SCATTER_GATHER 0x02U /*!< Scatter/gather performed after transfer completed. */ + +typedef void LDD_DMA_TData; +typedef uint8_t LDD_DMA_TTransactionSize; /* Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TTransactionCount; +typedef uint32_t LDD_DMA_TRequestCount; +typedef uint32_t LDD_DMA_TTransferDataSize; + +typedef uint32_t LDD_DMA_TAddress; /*!< Type specifying the address parameter used by the DMA component's methods. */ +typedef int32_t LDD_DMA_TAddressOffset; /*!< Type specifying the address signed offset parameter used by the DMA component's methods. */ +typedef uint32_t LDD_DMA_TByteCount; /*!< Type specifying the byte count/minor loop count parameter used by the DMA component's methods. */ +typedef uint8_t LDD_DMA_TTransferSize; /*!< Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TModuloSize; /*!< Type specifying the modulo size parameter used by the DMA component's methods. */ + /*!< This value power of two represents size of used circular buffer (0U - buffer disabled). See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TTriggerSource; /*!< Type specifying the trigger source signal number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TChannelNumber; /*!< Type specifying the DMA channel number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TRecordNumber; /*!< Type specifying the DMA descriptor record number. */ +typedef uint32_t LDD_DMA_TChannelMask; /*!< Type specifying the DMA channel mask. For possible values see channel mask constants. */ +typedef uint8_t LDD_DMA_TChannelPriority; /*!< Type specifying the DMA channel priority number. See the MCU manual for detail description of allowed values. */ +typedef uint16_t LDD_DMA_TOuterLoopCount; /*!< Type specifying the transfer outer/major loop count. */ +typedef uint8_t LDD_DMA_TAfterRequest; /*!< Type specifying the operation executed after request service is completed. */ +typedef uint8_t LDD_DMA_TAfterTransfer; /*!< Type specifying the operation executed after transfer service is completed. */ +typedef uint8_t LDD_DMA_TBandwidthControl; /*!< Type specifying the bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TErrorFlags; /*!< DMA controller error flags. See the DMA_LDD component's header file for detail description of allowed values. */ + +/*! Type specifying a DMA channel status. */ +typedef enum { + LDD_DMA_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_DONE, /*!< Transfer is completed, waiting to start of next transfer. */ + LDD_DMA_ERROR /*!< Error detected. */ +} LDD_DMA_TChannelStatus; + +/*! Type specifying a DMA transfer state. */ +typedef enum { + LDD_DMA_TRANSFER_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_TRANSFER_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_TRANSFER_ERROR /*!< Error detected. */ +} LDD_DMA_TTransferState; + +/*! Type specifying the DMA transfer mode. */ +typedef enum { + LDD_DMA_CYCLE_STEAL_TRANSFERS, /*!< Only single read/write transfer is done per one service request. */ + LDD_DMA_SINGLE_TRANSFER, /*!< Transfer of all bytes defined by Data size is done after single service request. */ + LDD_DMA_NESTED_TRANSFERS /*!< Sequence of transfers triggered by service requests. One request transfers number of bytes defined by Byte count value. */ +} LDD_DMA_TTransferMode; + +/*! Type specifying the DMA trigger source type. */ +typedef enum { + LDD_DMA_SW_TRIGGER, /*!< Explicit software trigger. */ + LDD_DMA_HW_TRIGGER, /*!< Peripheral device trigger. */ + LDD_DMA_ALWAYS_ENABLED_TRIGGER /*!< Always enabled trigger. */ +} LDD_DMA_TTriggerType; + +/*! Type specifying the DMA error information structure. */ +typedef struct { + LDD_DMA_TChannelNumber ChannelNumber; /*!< Last error recorded channel number. */ + LDD_DMA_TErrorFlags ErrorFlags; /*!< Channel error flags. */ +} LDD_DMA_TError; + +/*! Type specifying the DMA Transfer descriptor information structure. */ +typedef struct { + LDD_TUserData *UserDataPtr; /*!< User device data structure pointer to be returned by the DMA_LDD component's ISR to the dynamic callback of this transfer descriptor. */ + LDD_DMA_TAddress SourceAddress; /*!< Address of a DMA transfer source data. */ + LDD_DMA_TAddressOffset SourceAddressOffset; /*!< Offset to be added to the source address after each elemental read operation. */ + LDD_DMA_TTransferSize SourceTransferSize; /*!< Source data transfer size (size of a elemental read operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize SourceModuloSize; /*!< Source address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TAddress DestinationAddress; /*!< Address of a DMA transfer destination. */ + LDD_DMA_TAddressOffset DestinationAddressOffset; /*!< Offset to be added to the destination address after each elemental write operation. */ + LDD_DMA_TTransferSize DestinationTransferSize; /*!< Destination data transfer size (size of a elemental write operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize DestinationModuloSize; /*!< Destination address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TTransferMode TransferMode; /*!< Selects DMA transfer mode. For the description of allowed values see the LDD_DMA_TTransferMode type declaration. */ + LDD_DMA_TByteCount ByteCount; /*!< Size of data in bytes to be transferred in single transfer. */ + LDD_DMA_TOuterLoopCount OuterLoopCount; /*!< Number of the outer loop iteration in the Nested operation mode, otherwise should have value of one. */ + bool InnerLoopChannelLink; /*!< TRUE - Inner loop channel linking enabled (if the nested operation is used, then this item enables the minor (inner) loop channel linking). */ + LDD_DMA_TChannelNumber InnerLoopLinkedChannel; /*!< Linked DMA channel number (used only if the InnerLoopChannelLink item is set TRUE) */ + bool OuterLoopChannelLink; /*!< TRUE - Outer (major) loop channel linking is enabled. Enables channel linking after transfer completes. */ + LDD_DMA_TChannelNumber OuterLoopLinkedChannel; /*!< Outer (major) loop linked DMA channel number (used only if the OuterLoopChannelLink item is set TRUE). */ + LDD_DMA_TAfterRequest AfterRequestComplete; /*!< Type of an action after the elemental read/write operation is done. For the description of allowed values see the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAddressOffset AddressOffset; /*!< Address offset value. Address specified in AfterRequestComplete item is adjusted by stored value. See the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAfterTransfer AfterTransferComplete; /*!< Type of an action executed after the last transfer operation is done. For the description of allowed values see the LDD_DMA_TAfterTransfer type declaration. */ + LDD_DMA_TAddressOffset SourceAddressAdjustment; /*!< Source address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddressOffset DestinationAddressAdjustment; /*!< Destination address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddress ScatterGatherAddress; /*!< Scatter / gather address. Used only if the AfterTransferComplete item is set to LDD_DMA_SCATTER_GATHER. */ + LDD_DMA_TBandwidthControl BandwidthControl; /*!< DMA channel bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ + bool ChannelAutoSelection; /*!< TRUE - DMA channel autoselection engine is used. FALSE - DMA fixed channel is used. */ + LDD_DMA_TChannelNumber ChannelNumber; /*!< If ChannelAutoSelection is FALSE this item contains fixed channel number. If ChannelAutoSelection is TRUE then after allocation this item is filled by autoselected channel number. */ + LDD_DMA_TTriggerType TriggerType; /*!< DMA transfer trigger type. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + LDD_DMA_TTriggerSource TriggerSource; /*!< Trigger source number. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + bool PeriodicTrigger; /*!< TRUE - periodic trigger is required, FALSE - periodic trigger is not required. */ + bool DisableAfterRequest; /*!< TRUE - DMA transfer request is automatically disabled after transfer complete. */ + bool Interrupts; /*!< TRUE - interrupts are requested. */ + bool OnComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnHalfComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnError; /*!< TRUE - event is enabled during initialization. */ + void (*OnCompleteEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnComplete event, NULL if event is not used. */ + void (*OnErrorEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnError event, NULL if event is not used. */ + bool ChannelEnabled; /*!< TRUE - DMA channel is allocated and used by DMATransfer component. */ +} LDD_DMA_TTransferDescriptor; + +typedef LDD_DMA_TTransferDescriptor *LDD_DMA_TTransferDescriptorPtr; /*!< Type specifying address of the DMA Transfer descriptor structure. */ + +/* +** =================================================================== +** SPI device types and constants - SPIMaster_LDD +** =================================================================== +*/ + +#define LDD_SPIMASTER_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPIMASTER_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPIMASTER_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPIMASTER_CS_0_PIN 0x08U /*!< Chip select 0 pin mask */ +#define LDD_SPIMASTER_CS_1_PIN 0x10U /*!< Chip select 1 pin mask */ +#define LDD_SPIMASTER_CS_2_PIN 0x20U /*!< Chip select 2 pin mask */ +#define LDD_SPIMASTER_CS_3_PIN 0x40U /*!< Chip select 3 pin mask */ +#define LDD_SPIMASTER_CS_4_PIN 0x80U /*!< Chip select 4 pin mask */ +#define LDD_SPIMASTER_CS_5_PIN 0x0100U /*!< Chip select 5 pin mask */ +#define LDD_SPIMASTER_CS_6_PIN 0x0200U /*!< Chip select 6 pin mask */ +#define LDD_SPIMASTER_CS_7_PIN 0x0400U /*!< Chip select 7 pin mask */ +#define LDD_SPIMASTER_CSS_PIN 0x0800U /*!< Chip select strobe pin mask */ + +#define LDD_SPIMASTER_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPIMASTER_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPIMASTER_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPIMASTER_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPIMASTER_PARITY_ERROR 0x02U /*!< Parity error */ +#define LDD_SPIMASTER_RX_DMA_ERROR 0x04U /*!< Receive DMA channel error */ +#define LDD_SPIMASTER_TX_DMA_ERROR 0x08U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPIMASTER_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ +} LDD_SPIMASTER_TStats; + +/* +** =================================================================== +** SPI device types and constants - SPISlave_LDD +** =================================================================== +*/ + +#define LDD_SPISLAVE_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPISLAVE_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPISLAVE_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPISLAVE_SS_PIN 0x08U /*!< Slave select pin mask */ + +#define LDD_SPISLAVE_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPISLAVE_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPISLAVE_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPISLAVE_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPISLAVE_TX_UNDERFLOW 0x02U /*!< Transmitter underflow */ +#define LDD_SPISLAVE_PARITY_ERROR 0x04U /*!< Parity error */ +#define LDD_SPISLAVE_RX_DMA_ERROR 0x08U /*!< Receive DMA channel error */ +#define LDD_SPISLAVE_TX_DMA_ERROR 0x10U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPISLAVE_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ +} LDD_SPISLAVE_TStats; + +/* +** =================================================================== +** I2S device types and constants +** =================================================================== +*/ + +#define LDD_SSI_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SSI_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SSI_RX_CLK_PIN 0x04U /*!< Rx clock pin mask */ +#define LDD_SSI_TX_CLK_PIN 0x08U /*!< Tx clock pin mask */ +#define LDD_SSI_RX_FS_PIN 0x10U /*!< Rx frame sync pin mask */ +#define LDD_SSI_TX_FS_PIN 0x20U /*!< Tx frame sync pin mask */ +#define LDD_SSI_MCLK_PIN 0x40U /*!< Master clock pin mask */ +#define LDD_SSI_INPUT_PIN_CHANNEL_0 0x80U /*!< Input pin mask for data channel 0 */ +#define LDD_SSI_INPUT_PIN_CHANNEL_1 0x0100U /*!< Input pin mask for data channel 1 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_0 0x0200U /*!< Output pin mask for data channel 0 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_1 0x0400U /*!< Output pin mask for data channel 1 */ + +#define LDD_SSI_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SSI_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SSI_ON_ERROR 0x04u /*!< OnError event mask */ +#define LDD_SSI_ON_BLOCK_RECEIVED_1 0x08u /*!< OnBlockReceived event mask for second channel */ +#define LDD_SSI_ON_BLOCK_SENT_1 0x10u /*!< OnBlockSent event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_FRAME_SYNC 0x20u /*!< OnReceiveFrameSync event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_FRAME_SYNC 0x40u /*!< OnTransmitFrameSync event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_LAST_SLOT 0x80u /*!< OnReceiveLastSlot event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_LAST_SLOT 0x0100u /*!< OnTransmitLastSlot event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_COMPLETE 0x0200u /*!< OnReceiveComplete event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_COMPLETE 0x0400u /*!< OnTransmitComplete event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ + +#define LDD_SSI_RECEIVER 0x01U /*!< Receive section of the device. */ +#define LDD_SSI_TRANSMITTER 0x02U /*!< Transmit section of the device. */ + +#define LDD_SSI_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SSI_RX_OVERFLOW_1 0x02U /*!< Receiver overflow 1 */ +#define LDD_SSI_RX_SYNC_ERROR 0x04U /*!< Receiver frame sync error */ +#define LDD_SSI_RX_DMA_ERROR 0x08U /*!< Receiver DMA error */ + +#define LDD_SSI_TX_UNDERFLOW 0x10U /*!< Transmitter underflow */ +#define LDD_SSI_TX_UNDERFLOW_1 0x20U /*!< Transmitter underflow 1 */ +#define LDD_SSI_TX_SYNC_ERROR 0x40U /*!< Transmitter frame sync error */ +#define LDD_SSI_TX_DMA_ERROR 0x80U /*!< Transmitter DMA error */ + +#define LDD_SSI_RX_FRAME_COMPLETE 0x01U /*!< Receive frame is finished after disabling transfer */ +#define LDD_SSI_TX_FRAME_COMPLETE 0x02U /*!< Transmit frame is finished after disabling transfer */ +#define LDD_SSI_RX_FRAME_SYNC 0x04U /*!< Receiver frame sync */ +#define LDD_SSI_TX_FRAME_SYNC 0x08U /*!< Transmit frame sync */ +#define LDD_SSI_RX_LAST_SLOT 0x10U /*!< Receive last time slot */ +#define LDD_SSI_TX_LAST_SLOT 0x20U /*!< Transmit last time slot */ +#define LDD_SSI_AC97_TAG 0x40U /*!< AC97 tag updated */ +#define LDD_SSI_AC97_COMMAND_ADDRESS 0x80U /*!< AC97 command address updated */ +#define LDD_SSI_AC97_COMMAND_DATA 0x0100U /*!< AC97 command data updated */ + +typedef uint8_t LDD_SSI_TSectionMask; /*!< Device section type */ + +typedef uint32_t LDD_SSI_TError; /*!< Communication error type */ + +typedef uint32_t LDD_SSI_TComStatus; /*!< Communication status type */ + +/*! Group of pointers to data blocks. */ +typedef struct { + LDD_TData *Channel0Ptr; /*!< Pointer to data block to send/received via data channel 0 */ + LDD_TData *Channel1Ptr; /*!< Pointer to data block to send/received via data channel 1 */ +} LDD_SSI_TDataBlocks; + +/*! Command type */ +typedef enum { + LDD_SSI_READ_COMMAND = 0x08u, + LDD_SSI_WRITE_COMMAND = 0x10u +} LDD_SSI_TAC97CommandType; + +/*! AC97 command */ +typedef struct { + LDD_SSI_TAC97CommandType Type; /*!< Command type */ + uint32_t Address; /*!< Command address */ + uint32_t Data; /*!< Command data */ +} LDD_SSI_TAC97Command; + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ + uint32_t RxChars1; /*!< Number of received characters for second channel */ + uint32_t TxChars1; /*!< Number of transmitted characters for second channel */ + uint32_t RxOverruns1; /*!< Number of receiver overruns, which have occured for second channel */ + uint32_t TxUnderruns1; /*!< Number of transmitter underruns, which have occured for second channel */ +} LDD_SSI_TStats; + +/* +** =================================================================== +** RTC device types and constants +** =================================================================== +*/ + +#define LDD_RTC_ON_SECOND 0x10u /*!< OnSecond event mask */ +#define LDD_RTC_ON_MONOTONIC_OVERFLOW 0x08u /*!< OnMonotonicCounter event mask */ +#define LDD_RTC_ON_ALARM 0x04u /*!< OnAlarm event mask */ +#define LDD_RTC_ON_TIME_OVERFLOW 0x02u /*!< OnTimeOverflow event mask */ +#define LDD_RTC_ON_TIME_INVALID 0x01u /*!< OnTimeInvalid event mask */ +#define LDD_RTC_ON_STOPWATCH 0x0100u /*!< OnStopwatch event mask */ + +/*! Structure used for time operation */ +typedef struct { + uint32_t Second; /*!< seconds (0 - 59) */ + uint32_t Minute; /*!< minutes (0 - 59) */ + uint32_t Hour; /*!< hours (0 - 23) */ + uint32_t DayOfWeek; /*!< day of week (0-Sunday, .. 6-Saturday) */ + uint32_t Day; /*!< day (1 - 31) */ + uint32_t Month; /*!< month (1 - 12) */ + uint32_t Year; /*!< year */ +} LDD_RTC_TTime; + + + +/* +** =================================================================== +** CRC device types and constants +** =================================================================== +*/ + +#define LDD_CRC_16_SEED_LOW 0x00U /*!< CRC 16bit seed low */ +#define LDD_CRC_16_POLY_LOW 0x8005U /*!< CRC 16bit poly low */ +#define LDD_CRC_32_SEED_LOW 0xFFFFU /*!< CRC 32bit seed low */ +#define LDD_CRC_32_SEED_HIGH 0xFFFFU /*!< CRC 32bit seed high */ +#define LDD_CRC_32_POLY_LOW 0x1DB7U /*!< CRC 32bit poly low */ +#define LDD_CRC_32_POLY_HIGH 0x04C1U /*!< CRC 32bit poly high */ +#define LDD_CRC_CCITT_SEED_LOW 0xFFFFU /*!< CRC CCITT seed low */ +#define LDD_CRC_CCITT_POLY_LOW 0x1021U /*!< CRC CCITT poly low */ +#define LDD_CRC_MODBUS_16_SEED_LOW 0xFFFFU /*!< CRC MODBUS16 seed low */ +#define LDD_CRC_MODBUS_16_POLY_LOW 0x8005U /*!< CRC MODBUS16 poly low */ +#define LDD_CRC_KERMIT_SEED_LOW 0x00U /*!< CRC KERMIT seed low */ +#define LDD_CRC_KERMIT_POLY_LOW 0x1021U /*!< CRC KERMIT poly low */ +#define LDD_CRC_DNP_SEED_LOW 0x00U /*!< CRC DNP seed low */ +#define LDD_CRC_DNP_POLY_LOW 0x3D65U /*!< CRC DNP poly low */ + +/*! Transpose type */ +typedef enum { + LDD_CRC_NO_TRANSPOSE = 0, /*!< No transposition */ + LDD_CRC_BITS = 1, /*!< Bits are transposed */ + LDD_CRC_BITS_AND_BYTES = 2, /*!< Bits and bytes are transposed */ + LDD_CRC_BYTES = 3 /*!< Bytes are transposed */ +} LDD_CRC_TTransposeType; + +/*! CRC standard */ +typedef enum { + LDD_CRC_16, /*!< CRC16 standard */ + LDD_CRC_CCITT, /*!< CCITT standard */ + LDD_CRC_MODBUS_16, /*!< MODBUS16 standard */ + LDD_CRC_KERMIT, /*!< KERMIT standard */ + LDD_CRC_DNP, /*!< DNP standard */ + LDD_CRC_32, /*!< CRC32 standard */ + LDD_CRC_USER /*!< User defined type */ +} LDD_CRC_TCRCStandard; + +/*! User CRC standard */ +typedef struct { + bool Width32bit; /*!< 32bit CRC? */ + bool ResultXORed; /*!< Result XORed? */ + uint16_t SeedLow; /*!< Seed low value */ + uint16_t SeedHigh; /*!< Seed high value */ + uint16_t PolyLow; /*!< Poly low value */ + uint16_t PolyHigh; /*!< Poly high value */ + LDD_CRC_TTransposeType InputTransposeMode; /*!< Input transpose type */ + LDD_CRC_TTransposeType OutputTransposeMode; /*!< Output transpose type */ +} LDD_CRC_TUserCRCStandard; + +/* +** =================================================================== +** RNG device types and constants +** =================================================================== +*/ + + +#define LDD_RNG_LFSR_ERROR 0x01U /*!< Linear feedback shift register error */ +#define LDD_RNG_OSCILLATOR_ERROR 0x02U /*!< Oscillator error */ +#define LDD_RNG_SELF_TEST_ERROR 0x04U /*!< Self test error */ +#define LDD_RNG_STATISTICAL_ERROR 0x08U /*!< LStatistical test error */ +#define LDD_RNG_FIFO_UNDERFLOW_ERROR 0x10U /*!< FIFO underflow error */ + +#define LDD_RNG_SELF_TETS_RESEED_ERROR 0x00200000U /*!< Reseed self test fail */ +#define LDD_RNG_SELF_TEST_PRNG_ERROR 0x00400000U /*!< PRNG self test fail */ +#define LDD_RNG_SELF_TEST_TRNG_ERROR 0x00800000U /*!< TRNG self test fail */ +#define LDD_RNG_MONOBIT_TEST_ERROR 0x01000000U /*!< Monobit test fail */ +#define LDD_RNG_LENGTH_1_RUN_TEST_ERROR 0x02000000U /*!< Length 1 run test fail */ +#define LDD_RNG_LENGTH_2_RUN_TEST_ERROR 0x04000000U /*!< Length 2 run test fail */ +#define LDD_RNG_LENGTH_3_RUN_TEST_ERROR 0x08000000U /*!< Length 3 run test fail */ +#define LDD_RNG_LENGTH_4_RUN_TEST_ERROR 0x10000000U /*!< Length 4 run test fail */ +#define LDD_RNG_LENGTH_5_RUN_TEST_ERROR 0x20000000U /*!< Length 5 run test fail */ +#define LDD_RNG_LENGTH_6_RUN_TEST_ERROR 0x40000000U /*!< Length 6 run test fail */ +#define LDD_RNG_LONG_RUN_TEST_ERROR 0x80000000U /*!< Long run test fail */ + +#define LDD_RNG_ON_SEED_GENERATION_DONE 0x01U /*!< OnSeedGenerationDone event mask */ +#define LDD_RNG_ON_SELF_TEST_DONE 0x02U /*!< OnSelfTestDone event mask */ +#define LDD_RNG_ON_ERROR_LFSR 0x04U /*!< OnErrorLFSR event mask */ +#define LDD_RNG_ON_OSC_ERROR 0x08U /*!< OnOscError event mask */ +#define LDD_RNG_ON_SELF_TEST_ERROR 0x10U /*!< OnSelfTestError event mask */ +#define LDD_RNG_ON_STATISTICAL_ERROR 0x20U /*!< OnStatisticalError event mask */ +#define LDD_RNG_ON_FIFO_UNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ +#define LDD_RNG_ON_FIFOUNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ + +#define LDD_RNG_STATUS_ERROR 0xFFFFU /*!< Error in RNG module flag */ +#define LDD_RNG_STATUS_NEW_SEED_DONE 0x40U /*!< New seed done flag */ +#define LDD_RNG_STATUS_SEED_DONE 0x20U /*!< Seed done flag */ +#define LDD_RNG_STATUS_SELF_TEST_DONE 0x10U /*!< Self test done flag */ +#define LDD_RNG_STATUS_RESEED_NEEDED 0x08U /*!< Reseed needed flag */ +#define LDD_RNG_STATUS_SLEEP 0x04U /*!< RNG in sleep mode */ +#define LDD_RNG_STATUS_BUSY 0x02U /*!< RNG busy flag */ + + +/* +** =================================================================== +** RNGA device types and constants +** =================================================================== +*/ + +#define LDD_RNG_ON_ERROR 0x01U /*!< OnError event mask */ + +#define LDD_RNG_STATUS_SECURITY_VIOLATION 0x01U /*!< Security violation occured */ +#define LDD_RNG_STATUS_LAST_READ_UNDERFLOW 0x02U /*!< Last read from RNGA caused underflow error */ +#define LDD_RNG_STATUS_OUT_REG_UNDERFLOW 0x04U /*!< The RNGA Output Register has been read while empty since last read of the RNGA Status Register. */ +#define LDD_RNG_STATUS_ERR_INT_PENDING 0x08U /*!< Error interrupt pending */ +#define LDD_RNG_STATUS_SLEEP_MODE 0x10U /*!< Sleep mode enabled */ + +/*! RNGA sleep mode */ +typedef enum { + LDD_RNG_SLEEP_ENABLED, /*!< RNGA is in sleep mode */ + LDD_RNG_SLEEP_DISABLED /*!< RNGA is running */ +} LDD_RNG_TSleepMode; + +/* +** =================================================================== +** DryIce device types and constants +** =================================================================== +*/ + +#define LDD_DRY_ON_TAMPER_DETECTED 0x01U /*!< OnTamperDetected event mask */ + +/* Tamper flags */ +#define LDD_DRY_TIME_OVERFLOW 0x04U /*!< RTC time overflow has occurred. */ +#define LDD_DRY_MONOTONIC_OVERFLOW 0x08U /*!< RTC monotonic overflow has occurred. */ +#define LDD_DRY_VOLTAGE_TAMPER 0x10U /*!< VBAT voltage is outside of the valid range. */ +#define LDD_DRY_CLOCK_TAMPER 0x20U /*!< The 32.768 kHz clock source is outside the valid range. */ +#define LDD_DRY_TEMPERATURE_TAMPER 0x40U /*!< The junction temperature is outside of specification. */ +#define LDD_DRY_SECURITY_TAMPER 0x80U /*!< The (optional) security module asserted its tamper detect. */ +#define LDD_DRY_FLASH_SECURITY 0x0100U /*!< The flash security is disabled. */ +#define LDD_DRY_TEST_MODE 0x0200U /*!< Any test mode has been entered. */ +/* Tamper flags indicating that the pin does not equal its expected value and was not filtered by the glitch filter (if enabled). */ +#define LDD_DRY_TAMPER_PIN_0 0x00010000U /*!< Mismatch on tamper pin 0. */ +#define LDD_DRY_TAMPER_PIN_1 0x00020000U /*!< Mismatch on tamper pin 1. */ +#define LDD_DRY_TAMPER_PIN_2 0x00040000U /*!< Mismatch on tamper pin 2. */ +#define LDD_DRY_TAMPER_PIN_3 0x00080000U /*!< Mismatch on tamper pin 3. */ +#define LDD_DRY_TAMPER_PIN_4 0x00100000U /*!< Mismatch on tamper pin 4. */ +#define LDD_DRY_TAMPER_PIN_5 0x00200000U /*!< Mismatch on tamper pin 5. */ +#define LDD_DRY_TAMPER_PIN_6 0x00400000U /*!< Mismatch on tamper pin 6. */ +#define LDD_DRY_TAMPER_PIN_7 0x00800000U /*!< Mismatch on tamper pin 7. */ + +#define LDD_DRY_SECURE_KEY_WORD_0 0x01U /*!< Secure key word 0 mask */ +#define LDD_DRY_SECURE_KEY_WORD_1 0x02U /*!< Secure key word 1 mask */ +#define LDD_DRY_SECURE_KEY_WORD_2 0x04U /*!< Secure key word 2 mask */ +#define LDD_DRY_SECURE_KEY_WORD_3 0x08U /*!< Secure key word 3 mask */ +#define LDD_DRY_SECURE_KEY_WORD_4 0x10U /*!< Secure key word 4 mask */ +#define LDD_DRY_SECURE_KEY_WORD_5 0x20U /*!< Secure key word 5 mask */ +#define LDD_DRY_SECURE_KEY_WORD_6 0x40U /*!< Secure key word 6 mask */ +#define LDD_DRY_SECURE_KEY_WORD_7 0x80U /*!< Secure key word 7 mask */ + +/* +** =================================================================== +** NFC device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_NFC_ON_CMD_ERROR 0x01U /*!< OnCmdError event mask */ +#define LDD_NFC_ON_CMD_DONE 0x02U /*!< OnCmdDone event mask */ + +/* Pins' masks */ +#define LDD_NFC_CE0_PIN 0x01U /*!< CE0 pin mask */ +#define LDD_NFC_RB0_PIN 0x02U /*!< RB0 pin mask */ +#define LDD_NFC_CE1_PIN 0x04U /*!< CE1 pin mask */ +#define LDD_NFC_RB1_PIN 0x08U /*!< RB1 pin mask */ +#define LDD_NFC_CE2_PIN 0x10U /*!< CE2 pin mask */ +#define LDD_NFC_RB2_PIN 0x20U /*!< RB2 pin mask */ +#define LDD_NFC_CE3_PIN 0x40U /*!< CE3 pin mask */ +#define LDD_NFC_RB3_PIN 0x80U /*!< RB3 pin mask */ +#define LDD_NFC_ALE_PIN 0x0100U /*!< ALE pin mask */ +#define LDD_NFC_CLE_PIN 0x0200U /*!< CLE pin mask */ +#define LDD_NFC_RE_PIN 0x0400U /*!< RE pin mask */ +#define LDD_NFC_WE_PIN 0x0800U /*!< WE pin mask */ +#define LDD_NFC_D0_PIN 0x00010000U /*!< D0 pin mask */ +#define LDD_NFC_D1_PIN 0x00020000U /*!< D1 pin mask */ +#define LDD_NFC_D2_PIN 0x00040000U /*!< D2 pin mask */ +#define LDD_NFC_D3_PIN 0x00080000U /*!< D3 pin mask */ +#define LDD_NFC_D4_PIN 0x00100000U /*!< D4 pin mask */ +#define LDD_NFC_D5_PIN 0x00200000U /*!< D5 pin mask */ +#define LDD_NFC_D6_PIN 0x00400000U /*!< D6 pin mask */ +#define LDD_NFC_D7_PIN 0x00800000U /*!< D7 pin mask */ +#define LDD_NFC_D8_PIN 0x01000000U /*!< D8 pin mask */ +#define LDD_NFC_D9_PIN 0x02000000U /*!< D9 pin mask */ +#define LDD_NFC_D10_PIN 0x04000000U /*!< D10 pin mask */ +#define LDD_NFC_D11_PIN 0x08000000U /*!< D11 pin mask */ +#define LDD_NFC_D12_PIN 0x10000000U /*!< D12 pin mask */ +#define LDD_NFC_D13_PIN 0x20000000U /*!< D13 pin mask */ +#define LDD_NFC_D14_PIN 0x40000000U /*!< D14 pin mask */ +#define LDD_NFC_D15_PIN 0x80000000U /*!< D15 pin mask */ + +typedef uint32_t LDD_NFC_TTargetID; /*!< NFC target ID type */ + +/*! NCF command codes */ +typedef enum { + LDD_NFC_CMD_NONE = 0x00U, /* No command */ + LDD_NFC_CMD_RESET = 0x01U, /* Reset command */ + LDD_NFC_CMD_ERASE = 0x02U, /* Erase command */ + LDD_NFC_CMD_READ_ID = 0x03U, /* Read ID command */ + LDD_NFC_CMD_READ_PAGES = 0x04U, /* Read pages command */ + LDD_NFC_CMD_WRITE_PAGES = 0x05U, /* Write pages command */ + LDD_NFC_CMD_ERASE_BLOCKS = 0x06U, /* Erase page command */ + LDD_NFC_CMD_READ_RAW_PAGE = 0x07U, /* Read raw page command */ + LDD_NFC_CMD_WRITE_RAW_PAGE = 0x08U /* Write raw page command */ +} LDD_NFC_TeCmd; + +/* +** =================================================================== +** LCDC device types and constants +** =================================================================== +*/ + +#define LDD_LCDC_ON_ERROR 0x01U /*!< OnError event mask */ +#define LDD_LCDC_ON_START_OF_FRAME 0x02U /*!< OnStartOfFrame event mask */ +#define LDD_LCDC_ON_END_OF_FRAME 0x04U /*!< OnEndOfFrame event mask */ + +#define LDD_LCDC_NO_ERR 0x00U /*!< No error */ +#define LDD_LCDC_PLANE_0_UNDERRUN_ERR 0x01U /*!< Plane 0 underrurn error */ +#define LDD_LCDC_PLANE_1_UNDERRUN_ERR 0x02U /*!< Plane 1 underrurn error */ + +#define LDD_LCDC_REVERSED_VERTICAL_SCAN 0x8000U /*!< Enable reversed vertical scan (flip along x-axis) */ + +/*! Bitmap description */ +typedef struct { + LDD_TData *Address; /*!< Bitmap starting address */ + uint16_t Width; /*!< Bitmap width */ + uint16_t Height; /*!< Bitmap height */ + uint16_t Format; /*!< Bitmap format */ +} LDD_LCDC_TBitmap; + +/*! Window description */ +typedef struct { + uint16_t X; /*!< Window position in bitmap - X */ + uint16_t Y; /*!< Window position in bitmap - Y */ + uint16_t Width; /*!< Window width */ + uint16_t Height; /*!< Window height */ +} LDD_LCDC_TWindow; + +/*! Cursor type */ +typedef enum { + LDD_LCDC_DISABLED = 0, /*!< Cursor disabled */ + LDD_LCDC_ALWAYS_1, /*!< Cursor 1''s, monochrome display only. */ + LDD_LCDC_ALWAYS_0, /*!< Cursor 0''s, monochrome display only. */ + LDD_LCDC_COLOR, /*!< Defined cursor color, color display only. */ + LDD_LCDC_INVERTED, /*!< Inverted background, monochrome display only. */ + LDD_LCDC_INVERTED_COLOR, /*!< Inverted cursor color, color display only. */ + LDD_LCDC_AND, /*!< Cursor color AND backgroun, color display only. */ + LDD_LCDC_OR, /*!< Cursor color OR backgroun, color display only. */ + LDD_LCDC_XOR +} LDD_LCDC_CursorOperation; + +/*! Plane identification */ +typedef enum { + LDD_LCDC_PLANE_COMMON, /*!< Common for all planes */ + LDD_LCDC_PLANE_0, /*!< Plane (layer) 0 */ + LDD_LCDC_PLANE_1 /*!< Plane (layer) 1 */ +} LDD_LCDC_TPlaneID; + + +/* +** =================================================================== +** Interrupt vector constants +** =================================================================== +*/ +#define LDD_ivIndex_INT_Initial_Stack_Pointer 0x00u +#define LDD_ivIndex_INT_Initial_Program_Counter 0x01u +#define LDD_ivIndex_INT_NMI 0x02u +#define LDD_ivIndex_INT_Hard_Fault 0x03u +#define LDD_ivIndex_INT_Mem_Manage_Fault 0x04u +#define LDD_ivIndex_INT_Bus_Fault 0x05u +#define LDD_ivIndex_INT_Usage_Fault 0x06u +#define LDD_ivIndex_INT_Reserved7 0x07u +#define LDD_ivIndex_INT_Reserved8 0x08u +#define LDD_ivIndex_INT_Reserved9 0x09u +#define LDD_ivIndex_INT_Reserved10 0x0Au +#define LDD_ivIndex_INT_SVCall 0x0Bu +#define LDD_ivIndex_INT_DebugMonitor 0x0Cu +#define LDD_ivIndex_INT_Reserved13 0x0Du +#define LDD_ivIndex_INT_PendableSrvReq 0x0Eu +#define LDD_ivIndex_INT_SysTick 0x0Fu +#define LDD_ivIndex_INT_DMA0 0x10u +#define LDD_ivIndex_INT_DMA1 0x11u +#define LDD_ivIndex_INT_DMA2 0x12u +#define LDD_ivIndex_INT_DMA3 0x13u +#define LDD_ivIndex_INT_DMA_Error 0x14u +#define LDD_ivIndex_INT_Reserved21 0x15u +#define LDD_ivIndex_INT_FTFL 0x16u +#define LDD_ivIndex_INT_Read_Collision 0x17u +#define LDD_ivIndex_INT_LVD_LVW 0x18u +#define LDD_ivIndex_INT_LLW 0x19u +#define LDD_ivIndex_INT_Watchdog 0x1Au +#define LDD_ivIndex_INT_I2C0 0x1Bu +#define LDD_ivIndex_INT_SPI0 0x1Cu +#define LDD_ivIndex_INT_I2S0_Tx 0x1Du +#define LDD_ivIndex_INT_I2S0_Rx 0x1Eu +#define LDD_ivIndex_INT_UART0_LON 0x1Fu +#define LDD_ivIndex_INT_UART0_RX_TX 0x20u +#define LDD_ivIndex_INT_UART0_ERR 0x21u +#define LDD_ivIndex_INT_UART1_RX_TX 0x22u +#define LDD_ivIndex_INT_UART1_ERR 0x23u +#define LDD_ivIndex_INT_UART2_RX_TX 0x24u +#define LDD_ivIndex_INT_UART2_ERR 0x25u +#define LDD_ivIndex_INT_ADC0 0x26u +#define LDD_ivIndex_INT_CMP0 0x27u +#define LDD_ivIndex_INT_CMP1 0x28u +#define LDD_ivIndex_INT_FTM0 0x29u +#define LDD_ivIndex_INT_FTM1 0x2Au +#define LDD_ivIndex_INT_CMT 0x2Bu +#define LDD_ivIndex_INT_RTC 0x2Cu +#define LDD_ivIndex_INT_RTC_Seconds 0x2Du +#define LDD_ivIndex_INT_PIT0 0x2Eu +#define LDD_ivIndex_INT_PIT1 0x2Fu +#define LDD_ivIndex_INT_PIT2 0x30u +#define LDD_ivIndex_INT_PIT3 0x31u +#define LDD_ivIndex_INT_PDB0 0x32u +#define LDD_ivIndex_INT_USB0 0x33u +#define LDD_ivIndex_INT_USBDCD 0x34u +#define LDD_ivIndex_INT_TSI0 0x35u +#define LDD_ivIndex_INT_MCG 0x36u +#define LDD_ivIndex_INT_LPTimer 0x37u +#define LDD_ivIndex_INT_PORTA 0x38u +#define LDD_ivIndex_INT_PORTB 0x39u +#define LDD_ivIndex_INT_PORTC 0x3Au +#define LDD_ivIndex_INT_PORTD 0x3Bu +#define LDD_ivIndex_INT_PORTE 0x3Cu +#define LDD_ivIndex_INT_SWI 0x3Du + +#endif /* __PE_Types_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.c new file mode 100644 index 0000000..df3ea12 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.c @@ -0,0 +1,563 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:40, # CodeGen: 32 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 1 +** Number of Down Channels : 1 +** Max Blocked Interrupt Level : 3 +** Syscalls : no +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +/* MODULE RTT1. */ + +#include "RTT1.h" +#include "WAIT1.h" + +/* default standard I/O struct */ +CLS1_ConstStdIOType RTT1_stdio = { + (CLS1_StdIO_In_FctType)RTT1_StdIOReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stderr */ + RTT1_StdIOKeyPressed /* if input is not empty */ + }; +uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ +/** +int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ +/** +int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ +/** +unsigned RTT1_WriteString(unsigned BufferIndex, const char* s) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ +/** +dword RTT1_GetKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ +/** +long RTT1_WaitKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ +/** +long RTT1_HasKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ +bool RTT1_StdIOKeyPressed(void) +{ + return RTT1_HasKey()!=0; +} + +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOReadChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + *c = '\0'; + } else { + *c = (uint8_t)res; /* return character */ + } +} + +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOSendChar(uint8_t ch) +{ +#if RTT1_CONFIG_BLOCKING_SEND + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 && RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + int timeoutMs = RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif + + for(;;) { /* will break */ + if (RTT1_Write(0, (const char*)&ch, 1)==1) { /* non blocking send, check that we were able to send */ + break; /* was able to send character, get out of waiting loop */ + } + #if RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + WAIT1_WaitOSms(RTT1_CONFIG_BLOCKING_SEND_WAIT_MS); + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= RTT1_CONFIG_BLOCKING_SEND_WAIT_MS; + #endif + #endif + } /* for */ +#else + (void)RTT1_Write(0, &ch, 1); /* non blocking send, might loose characters */ +#endif +} + +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t RTT1_RecvChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + return ERR_RXEMPTY; + } + *c = (uint8_t)res; /* return character */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ +uint8_t RTT1_SendChar(uint8_t ch) +{ + int res; + + res = SEGGER_RTT_Write(0, (const char*)&ch, 1); + if (res!=1) { + return ERR_TXFULL; /* character not sent? */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ +/** +uint16_t RTT1_GetCharsInRxBuf(void) +{ + // Function is implemented as macro in the header file + if (SEGGER_RTT_HasKey()) { + return 1; // at least one available + } + return 0; // none available +} +*/ + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_TerminalOut(char TerminalId, const char* s) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_SetTerminal(char TerminalId) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Deinit(void) +{ + /* noting to de-initialize */ +} + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Init(void) +{ + SEGGER_RTT_Init(); +} + +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void) +{ + return &RTT1_stdio; +} + +/* END RTT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.h new file mode 100644 index 0000000..f4119ff --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1.h @@ -0,0 +1,476 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 1 +** Number of Down Channels : 1 +** Max Blocked Interrupt Level : 3 +** Syscalls : no +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +#ifndef __RTT1_H +#define __RTT1_H + +/* MODULE RTT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +/* Include inherited components */ +#include "WAIT1.h" +#include "MCUC1.h" +#include "CLS1.h" + + +#include "SEGGER_RTT.h" + + +#define RTT1_RTT_CHANNEL_0_ENABLED 1 /* 0: channel disabled, 1: channel enabled */ + +extern uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +extern CLS1_ConstStdIOType RTT1_stdio; /* default standard I/O */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTT1_Read(BufferIndex, pBuffer, NumBytes) \ + SEGGER_RTT_Read(BufferIndex, pBuffer, NumBytes) + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ + +#define RTT1_Write(BufferIndex, pBuffer, BufferSize) \ + SEGGER_RTT_Write(BufferIndex, pBuffer, BufferSize) + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ + +#define RTT1_WriteString(BufferIndex, s) \ + SEGGER_RTT_WriteString(BufferIndex, s) + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ + +#define RTT1_GetKey() \ + SEGGER_RTT_GetKey() + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ + +#define RTT1_WaitKey() \ + SEGGER_RTT_WaitKey() + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ + +#define RTT1_HasKey() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ + +bool RTT1_StdIOKeyPressed(void); +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ + +void RTT1_StdIOReadChar(uint8_t *c); +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ + +void RTT1_StdIOSendChar(uint8_t ch); +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ + +uint8_t RTT1_RecvChar(uint8_t *c); +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t RTT1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ + +#define RTT1_GetCharsInRxBuf() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ + +void RTT1_Init(void); + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define RTT1_TerminalOut(TerminalId, s) \ + SEGGER_RTT_TerminalOut(TerminalId, s) + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_SetTerminal(TerminalId) \ + SEGGER_RTT_SetTerminal(TerminalId) + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_printf \ + SEGGER_RTT_printf + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ + +void RTT1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END RTT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __RTT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1config.h new file mode 100644 index 0000000..0e2e01a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT1config.h @@ -0,0 +1,56 @@ +/** + * \file + * \brief Configuration header file for Segger RTT + * + * This header file is used to configure settings of the Segger RTT Module. + */ + +#ifndef __RTT1_CONFIG_H +#define __RTT1_CONFIG_H + +#ifndef RTT1_CONFIG_PROVIDE_SYSCALLS + #define RTT1_CONFIG_PROVIDE_SYSCALLS (0) + /*!< 1: RTT library implements SysCalls; 0: no Syscalls implemented */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND + #define RTT1_CONFIG_BLOCKING_SEND (1) + /*!< 1: using blocking call for stdio calls; 0: do not using blocking calls */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (5) + /*!< Timeout value for blocking calls for sending. Use zero for no timeout */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_WAIT_MS + #define RTT1_CONFIG_BLOCKING_SEND_WAIT_MS (1) + /*!< Waiting time during blocking send. Use zero for no waiting time */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_UP + #define RTT1_CONFIG_RTT_BUFFER_SIZE_UP (512) + /*!< Size of the up (Tx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN + #define RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN (64) + /*!< Size of the down (Rx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF + #define RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF (64) + /*!< Size of the buffer for RTT printf() in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_UP_BUFFER_MODE + #define RTT1_CONFIG_RTT_UP_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#ifndef RTT1_CONFIG_RTT_DOWN_BUFFER_MODE + #define RTT1_CONFIG_RTT_DOWN_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#endif /* __RTT1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/RTT_Syscalls_GCC.c b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT_Syscalls_GCC.c new file mode 100644 index 0000000..9ebed3e --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/RTT_Syscalls_GCC.c @@ -0,0 +1,203 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) + +#if 0 /* << EST moved to below */ +#include // required for _write_r +#endif +#include "SEGGER_RTT.h" + +#if RTT1_CONFIG_PROVIDE_SYSCALLS /* << EST */ +#include /* for EOF */ /* << EST */ +#include // required for _write_r // << EST moved from above + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +#if 0 +int _write(int file, char *ptr, int len); +int _write_r(struct _reent *r, int file, const void *ptr, int len); +#else /* << EST */ +extern int _write(int file, char *ptr, int len); +extern _ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); +#endif + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +int _write(int file, char *ptr, int len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +#if 0 +int _write_r(struct _reent *r, int file, const void *ptr, int len) { +#else /* << EST */ +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) { +#endif + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +int _putc(int c, __FILE *fp) { /* << EST */ + char ch = c; + (void)fp; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _putchar(int c) { /* << EST */ + char ch = c; + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _getc(__FILE *fp) { /* << EST */ + char ch; + (void)fp; /* Not used, avoid warning */ + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return ch; +} + +int _read(void) { + uint8_t ch; + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return (int)ch; +} + +int __attribute__((weak)) _isatty(int file __attribute__((unused))) { + return 1; +} + +int __attribute__((weak)) _close(int fildes __attribute__((unused))) { + return -1; +} + +int __attribute__((weak)) _lseek(int file __attribute__((unused)), int ptr __attribute__((unused)), int dir __attribute__((unused))) { + return -1; +} + +#if 0 +int __attribute__((weak)) _fstat (int fd __attribute__((unused)), struct stat *st) +{ + memset (st, 0, sizeof(*st)); + st->st_mode = S_IFCHR; + return 0; +} +#endif + + +#endif /* RTT1_CONFIG_PROVIDE_SYSCALLS */ /* << EST */ + +#endif +/****** End Of File *************************************************/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Rx1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Rx1.c new file mode 100644 index 0000000..8bc5d91 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Rx1.c @@ -0,0 +1,437 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Rx1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : RingBuffer +** Version : Component 01.053, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** This component implements a ring buffer for different integer data type. +** Settings : +** Component name : Rx1 +** Buffer Size : 64 +** Contents : +** Clear - void Rx1_Clear(void); +** Put - uint8_t Rx1_Put(Rx1_ElementType elem); +** Get - uint8_t Rx1_Get(Rx1_ElementType *elemP); +** Peek - uint8_t Rx1_Peek(Rx1_BufSizeType index, Rx1_ElementType *elemP); +** Update - uint8_t Rx1_Update(Rx1_BufSizeType index, Rx1_ElementType *elemP); +** Putn - uint8_t Rx1_Putn(Rx1_ElementType *elem, Rx1_BufSizeType nof); +** Getn - uint8_t Rx1_Getn(Rx1_ElementType *buf, Rx1_BufSizeType nof); +** Compare - uint8_t Rx1_Compare(Rx1_BufSizeType index, Rx1_ElementType *elemP,... +** Delete - uint8_t Rx1_Delete(void); +** NofElements - Rx1_BufSizeType Rx1_NofElements(void); +** NofFreeElements - Rx1_BufSizeType Rx1_NofFreeElements(void); +** Deinit - void Rx1_Deinit(void); +** Init - void Rx1_Init(void); +** +** * Copyright (c) 2014-2018, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file Rx1.h +** @version 01.00 +** @brief +** This component implements a ring buffer for different integer data type. +*/ +/*! +** @addtogroup Rx1_module Rx1 module documentation +** @{ +*/ + +/* MODULE Rx1. */ + +#include "Rx1.h" + +#if Rx1_CONFIG_REENTRANT + #define Rx1_DEFINE_CRITICAL() CS1_CriticalVariable() + #define Rx1_ENTER_CRITICAL() CS1_EnterCritical() + #define Rx1_EXIT_CRITICAL() CS1_ExitCritical() +#else + #define Rx1_DEFINE_CRITICAL() /* nothing */ + #define Rx1_ENTER_CRITICAL() /* nothing */ + #define Rx1_EXIT_CRITICAL() /* nothing */ +#endif +static Rx1_ElementType Rx1_buffer[Rx1_CONFIG_BUF_SIZE]; /* ring buffer */ +static Rx1_BufSizeType Rx1_inIdx; /* input index */ +static Rx1_BufSizeType Rx1_outIdx; /* output index */ +static Rx1_BufSizeType Rx1_inSize; /* size data in buffer */ +/* +** =================================================================== +** Method : Put (component RingBuffer) +** +** Description : +** Puts a new element into the buffer +** Parameters : +** NAME - DESCRIPTION +** elem - New element to be put into the buffer +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Put(Rx1_ElementType elem) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==Rx1_CONFIG_BUF_SIZE) { + res = ERR_TXFULL; + } else { + Rx1_buffer[Rx1_inIdx] = elem; + Rx1_inIdx++; + if (Rx1_inIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_inIdx = 0; + } + Rx1_inSize++; + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Putn (component RingBuffer) +** +** Description : +** Put a number new element into the buffer. +** Parameters : +** NAME - DESCRIPTION +** * elem - Pointer to new elements to be put into +** the buffer +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Putn(Rx1_ElementType *elem, Rx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Rx1_Put(*elem); + if (res!=ERR_OK) { + break; + } + elem++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : Get (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : +** NAME - DESCRIPTION +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Get(Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + *elemP = Rx1_buffer[Rx1_outIdx]; + Rx1_inSize--; + Rx1_outIdx++; + if (Rx1_outIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_outIdx = 0; + } + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Getn (component RingBuffer) +** +** Description : +** Get a number elements into a buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer where to store the +** elements +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Getn(Rx1_ElementType *buf, Rx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Rx1_Get(buf); + if (res!=ERR_OK) { + break; + } + buf++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : NofElements (component RingBuffer) +** +** Description : +** Returns the actual number of elements in the buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Rx1_BufSizeType Rx1_NofElements(void) +{ + return Rx1_inSize; +} + +/* +** =================================================================== +** Method : NofFreeElements (component RingBuffer) +** +** Description : +** Returns the actual number of free elements/space in the +** buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Rx1_BufSizeType Rx1_NofFreeElements(void) +{ + return (Rx1_BufSizeType)(Rx1_CONFIG_BUF_SIZE-Rx1_inSize); +} + +/* +** =================================================================== +** Method : Init (component RingBuffer) +** +** Description : +** Initializes the data structure +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Rx1_Init(void) +{ + Rx1_inIdx = 0; + Rx1_outIdx = 0; + Rx1_inSize = 0; +} + +/* +** =================================================================== +** Method : Clear (component RingBuffer) +** +** Description : +** Clear (empty) the ring buffer. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Rx1_Clear(void) +{ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + Rx1_Init(); + Rx1_EXIT_CRITICAL(); +} + +/* +** =================================================================== +** Method : Peek (component RingBuffer) +** +** Description : +** Returns an element of the buffer without removiing it. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Peek(Rx1_BufSizeType index, Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (index>=Rx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index0) { + res = Rx1_Peek(index, &val); + if (res!=ERR_OK) { /* general failure? */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + if (val!=*elemP) { /* mismatch */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + elemP++; index++; nof--; + } + + return cmpResult; +} + +/* +** =================================================================== +** Method : Deinit (component RingBuffer) +** +** Description : +** Driver de-initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void Rx1_Deinit(void) +{ + ** Function is implemented as macro in the header file +} +*/ +/* +** =================================================================== +** Method : Delete (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Delete(void) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + Rx1_inSize--; + Rx1_outIdx++; + if (Rx1_outIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_outIdx = 0; + } + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Update (component RingBuffer) +** +** Description : +** Updates the data of an element. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Update(Rx1_BufSizeType index, Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (index>=Rx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (indexT Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; +#if 1 /* << EST */ + p->aUp[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_UP; +#else + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; +#if 1 /* << EST */ + p->aDown[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_DOWN; +#else + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + const char* pSrc; +#endif + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytes -= Rem; + WrOff = NumBytes; + do { + *pDst++ = *pData++; + } while (--Rem); + pDst = pRing->pBuffer; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, Rem); + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; +#endif + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFu; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +#if 1 /* << EST: extra function */ +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex) { /* << EST */ + unsigned int avail; + + INIT(); + SEGGER_RTT_LOCK(); + avail = _GetAvailWriteSpace(&_SEGGER_RTT.aUp[bufferIndex]); + SEGGER_RTT_UNLOCK(); + return avail; +} +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT.h b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT.h new file mode 100644 index 0000000..bfe4fbf --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT.h @@ -0,0 +1,257 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 10533 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex); /* << EST */ +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); + +int SEGGER_printf(const char * sFormat, ...); /* << EST */ + +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_Conf.h b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..c7c610a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_Conf.h @@ -0,0 +1,355 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 9599 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +/* << EST: Additional setting to check for FreeRTOS: need to use FreeRTOS with proper BASEPRI mask to create critical sections */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +#if MCUC1_CONFIG_SDK_USE_FREERTOS + #include "portmacro.h" /* include FreeRTOS port header file for critical section handling */ +#endif + +/* Channel 0 settings from properties */ /* << EST */ +#define SEGGER_RTT_CHANNEL_0_ENABLED (1) /* 1: initialize channel; 0: do not initialize channel */ +#define SEGGER_RTT_CHANNEL_0_NAME "Terminal" +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) +#define SEGGER_RTT_CHANNEL_0_MODE_UP SEGGER_RTT_MODE_NO_BLOCK_SKIP +#define SEGGER_RTT_CHANNEL_0_MODE_DOWN SEGGER_RTT_MODE_NO_BLOCK_SKIP + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (1) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (1) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + /* >> EST */ + #if SEGGER_RTT_FREERTOS_PRESENT + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY /* Interrupts at this level and below will be blocked (valid values 1-15) */ + #else + #define SEGGER_RTT_LOCK_INTERRUPT_LEVEL 3 /* Interrupts at this level and below will be blocked (valid values 1-15 for Kinetis) */ + #define SEGGER_RTT_PRIO_BITS 4 /* NXP Kinetis M4(F) has 4 interrupt priority bits */ + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY (SEGGER_RTT_LOCK_INTERRUPT_LEVEL<<(8-SEGGER_RTT_PRIO_BITS)) + #endif + /* >> EST */ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY) /* input */\ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = OS_GetBASEPRI(); \ + OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_printf.c b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_printf.c new file mode 100644 index 0000000..bc2f57f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/SEGGER_RTT_printf.c @@ -0,0 +1,563 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } +#if 0 + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; +#else /* << EST: Do not count the characters twice! */ + BufferDesc.ReturnValue = (int)BufferDesc.Cnt; +#endif + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} + +#if 0 /* << EST extension to support extra format characters like %f */ +#include "McuXFormat.h" +#include "McuWait.h" + +int SEGGER_printf(const char * sFormat, ...) { + static char buffer[256]; /* NOT reentrant! */ + va_list args; + int res; + unsigned int avail; + + va_start(args, sFormat); + res = xsnprintf(buffer, sizeof(buffer), sFormat, args); + va_end(args); + if (res > 0) { + int retry = 5; + + do { + /* res is the number of characters written */ + avail = SEGGER_RTT_GetUpBufferFreeSize(0); + if (avail>res) { + break; /* enough space available */ + } else { + McuWait_Waitms(50); + retry--; + } + } while(retry>0); + return SEGGER_RTT_printf(0, "%s", buffer); + } + return -1; /* failed */ +} +#else +int SEGGER_printf(const char * sFormat, ...) { + va_list ParamList; + int res; + + va_start(ParamList, sFormat); + res = SEGGER_RTT_vprintf(0, sFormat, &ParamList); + va_end(ParamList); + return res; +} +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Step.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Step.c new file mode 100644 index 0000000..85602a0 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Step.c @@ -0,0 +1,192 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Step.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Step +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool Step_GetVal(void); +** PutVal - void Step_PutVal(bool Val); +** ClrVal - void Step_ClrVal(void); +** SetVal - void Step_SetVal(void); +** NegVal - void Step_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Step.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Step_module Step module documentation +** @{ +*/ + +/* MODULE Step. */ + +#include "Step.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : Step_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool Step_GetVal(void) + +** This method is implemented as a macro. See Step.h file. ** +*/ + +/* +** =================================================================== +** Method : Step_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void Step_PutVal(bool Val) + +** This method is implemented as a macro. See Step.h file. ** +*/ + +/* +** =================================================================== +** Method : Step_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void Step_ClrVal(void) + +** This method is implemented as a macro. See Step.h file. ** +*/ + +/* +** =================================================================== +** Method : Step_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void Step_SetVal(void) + +** This method is implemented as a macro. See Step.h file. ** +*/ + +/* +** =================================================================== +** Method : Step_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void Step_NegVal(void) + +** This method is implemented as a macro. See Step.h file. ** +*/ + +/* END Step. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Step.h b/Projects/tinyK20_SolderDispenser/Generated_Code/Step.h new file mode 100644 index 0000000..910e864 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Step.h @@ -0,0 +1,188 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Step.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : Step +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool Step_GetVal(void); +** PutVal - void Step_PutVal(bool Val); +** ClrVal - void Step_ClrVal(void); +** SetVal - void Step_SetVal(void); +** NegVal - void Step_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Step.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup Step_module Step module documentation +** @{ +*/ + +#ifndef __Step_H +#define __Step_H + +/* MODULE Step. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd2.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : Step_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define Step_GetVal() (BitIoLdd2_GetVal(BitIoLdd2_DeviceData)) + +/* +** =================================================================== +** Method : Step_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define Step_PutVal(Val) (BitIoLdd2_PutVal(BitIoLdd2_DeviceData, (Val))) + +/* +** =================================================================== +** Method : Step_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define Step_ClrVal() (BitIoLdd2_ClrVal(BitIoLdd2_DeviceData)) + +/* +** =================================================================== +** Method : Step_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define Step_SetVal() (BitIoLdd2_SetVal(BitIoLdd2_DeviceData)) + +/* +** =================================================================== +** Method : Step_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define Step_NegVal() (BitIoLdd2_NegVal(BitIoLdd2_DeviceData)) + +/* END Step. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __Step_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.c new file mode 100644 index 0000000..0d7b1c7 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.c @@ -0,0 +1,146 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TI1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerInt +** Version : Component 02.161, Driver 01.02, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This component "TimerInt" implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** The source of periodic interrupt can be timer compare or reload +** register or timer-overflow interrupt (of free running counter). +** Settings : +** Component name : TI1 +** Periodic interrupt source : FTM0_MOD +** Counter : FTM0_CNT +** Interrupt service/event : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Interrupt period : 500 µs +** Same period in modes : yes +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : no +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** TimerInt_LDD : TimerInt_LDD +** Contents : +** Enable - byte TI1_Enable(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TI1.c +** @version 01.02 +** @brief +** This component "TimerInt" implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** The source of periodic interrupt can be timer compare or reload +** register or timer-overflow interrupt (of free running counter). +*/ +/*! +** @addtogroup TI1_module TI1 module documentation +** @{ +*/ + +/* MODULE TI1. */ + +#include "Events.h" +#include "TI1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : TI1_Enable (component TimerInt) +** Description : +** This method enables the component - it starts the timer. +** Events may be generated (/). +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +/* +byte TI1_Enable(void) + +** This method is implemented as a macro. See TI1.h file. ** +*/ + +/* +** =================================================================== +** Method : TI1_OnInterrupt (component TimerInt) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void TimerIntLdd1_OnInterrupt(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + TI1_OnInterrupt(); /* Invoke OnInterrupt event */ +} + +/* END TI1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.h new file mode 100644 index 0000000..72e884b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TI1.h @@ -0,0 +1,153 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TI1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerInt +** Version : Component 02.161, Driver 01.02, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This component "TimerInt" implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** The source of periodic interrupt can be timer compare or reload +** register or timer-overflow interrupt (of free running counter). +** Settings : +** Component name : TI1 +** Periodic interrupt source : FTM0_MOD +** Counter : FTM0_CNT +** Interrupt service/event : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Interrupt period : 500 µs +** Same period in modes : yes +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : no +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** TimerInt_LDD : TimerInt_LDD +** Contents : +** Enable - byte TI1_Enable(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TI1.h +** @version 01.02 +** @brief +** This component "TimerInt" implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** The source of periodic interrupt can be timer compare or reload +** register or timer-overflow interrupt (of free running counter). +*/ +/*! +** @addtogroup TI1_module TI1 module documentation +** @{ +*/ + +#ifndef __TI1_H +#define __TI1_H + +/* MODULE TI1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "TimerIntLdd1.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : TI1_Enable (component TimerInt) +** Description : +** This method enables the component - it starts the timer. +** Events may be generated (/). +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +#define TI1_Enable() (TimerIntLdd1_Enable(TimerIntLdd1_DeviceData)) + +/* +** =================================================================== +** Method : TI1_OnInterrupt (component TimerInt) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void TimerIntLdd1_OnInterrupt(LDD_TUserData *UserDataPtr); + +/* END TI1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __TI1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TMOUT1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/TMOUT1.c new file mode 100644 index 0000000..27c5907 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TMOUT1.c @@ -0,0 +1,283 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TMOUT1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Timeout +** Version : Component 01.037, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +The module implements timeout functionality. With this implementation, +it is possible to wait for a given time, and the time is counted by +a periodic interrupt. +** Settings : +** Component name : TMOUT1 +** Maximum counters : 1 +** Counter tick period (ms) : 10 +** RTOS : Disabled +** Contents : +** GetCounter - TMOUT1_CounterHandle TMOUT1_GetCounter(TMOUT1_CounterType nofTicks); +** LeaveCounter - void TMOUT1_LeaveCounter(TMOUT1_CounterHandle handle); +** Value - TMOUT1_CounterType TMOUT1_Value(TMOUT1_CounterHandle handle); +** SetCounter - TMOUT1_CounterType TMOUT1_SetCounter(TMOUT1_CounterHandle handle,... +** CounterExpired - bool TMOUT1_CounterExpired(TMOUT1_CounterHandle handle); +** AddTick - void TMOUT1_AddTick(void); +** Init - void TMOUT1_Init(void); +** +** * Copyright (c) 2011-2016, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file TMOUT1.h +** @version 01.00 +** @brief +** +The module implements timeout functionality. With this implementation, +it is possible to wait for a given time, and the time is counted by +a periodic interrupt. +*/ +/*! +** @addtogroup TMOUT1_module TMOUT1 module documentation +** @{ +*/ + +/* MODULE TMOUT1. */ + +#include "TMOUT1.h" + +#define TMOUT1_NOF_COUNTERS 1 /* number of timeout counters available */ + +static TMOUT1_CounterType TMOUT1_Counters[TMOUT1_NOF_COUNTERS]; /* array of timeout counters */ +static bool TMOUT1_FreeCounters[TMOUT1_NOF_COUNTERS]; /* array to indicate which counters are free */ + +/* +** =================================================================== +** Method : GetCounter (component Timeout) +** +** Description : +** Initializes a new timeout counter and returns the handle to +** it. At the end, use LeaveCounter() to free up the resource. +** Parameters : +** NAME - DESCRIPTION +** nofTicks - Number of ticks for the counter +** until it expires. +** Returns : +** --- - Handle to the counter, to be used for +** further API calls. +** =================================================================== +*/ +TMOUT1_CounterHandle TMOUT1_GetCounter(TMOUT1_CounterType nofTicks) +{ + TMOUT1_CounterHandle handle; + CS1_CriticalVariable(); + + handle = 0; + if (nofTicks==0) { + nofTicks = 1; /* wait at least for one tick, otherwise will timeout immediately */ + } + CS1_EnterCritical(); + while (handle0) { + TMOUT1_Counters[i]--; + } + } + CS1_ExitCritical(); +} + +/* +** =================================================================== +** Method : Init (component Timeout) +** +** Description : +** Initialization of the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void TMOUT1_Init(void) +{ + uint8_t i; + + for(i=0;i /* for NULL */ +#include "FreeRTOS.h" +#include "task.h" + +/*! + \brief Descriptor defining a trigger. Triggers are used set as 'reminders' for the future. +*/ +typedef struct TriggerDesc { + uint16_t triggerTime; /*!< trigger 'time' in ticks */ + void (*callback)(void); /*!< callback function */ +} TriggerDesc; + +static TriggerDesc TriggerList[2]; /*!< Array of triggers */ + +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif +/* Internal method prototypes */ +static bool CheckCallbacks(void); + +/* +** =================================================================== +** Method : AddTrigger (component Trigger) +** +** Description : +** Adds a trigger +** Parameters : +** NAME - DESCRIPTION +** trigger - The trigger to be added +** incTicks - Trigger time, in trigger ticks. +** The time will is relative to the current +** tick time +** callback - Callback to be called when the +** trigger fires +** Returns : Nothing +** =================================================================== +*/ +void TRG1_AddTrigger(uint8_t trigger, uint16_t incTicks, void (*callback)(void)) +{ + CS1_CriticalVariable(); + + /* method can be called from an interrupt service routine! */ + CS1_EnterCritical(); + TriggerList[trigger].triggerTime = incTicks; + TriggerList[trigger].callback = callback; + CS1_ExitCritical(); +} + +/* +** =================================================================== +** Method : CheckCallbacks (component Trigger) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static bool CheckCallbacks(void) +{ + /* This method is called from TRG1_AddTick() which is called from a timer interrupt! */ + uint8_t i; /* counter through all triggers */ + void (*callback)(void); /* variable to temporarily store the callback pointer */ + bool calledCallBack = FALSE; /* flag to indicate if the callback has been called */ + CS1_CriticalVariable(); + + for(i=0;i__PRESS' */ 0 +#define TRG1_EXAMPLE /* example trigger */ 1 + +#define TRG1_CONFIG_TICK_PERIOD_MS \ + 10 /* Period in milliseconds as defined in component properties, at which TRG1._AddTick() is called */ + +#endif /* __TRG1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.c new file mode 100644 index 0000000..f045154 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.c @@ -0,0 +1,284 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : uint16_t +** Input clock source : Internal +** Counter frequency : Auto select +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 500 µs +** Interrupt : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : no +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); +** Enable - LDD_TError TU1_Enable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU1.c +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU1_module TU1 module documentation +** @{ +*/ + +/* MODULE TU1. */ + +#include "TimerIntLdd1.h" +#include "TU1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + LDD_TEventMask EnEvents; /* Enable/Disable events mask */ + uint32_t Source; /* Current source clock */ + uint8_t InitCntr; /* Number of initialization */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} TU1_TDeviceData; + +typedef TU1_TDeviceData *TU1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static TU1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static TU1_TDeviceDataPtr INT_FTM0__BAREBOARD_RTOS_ISRPARAM; + +#define AVAILABLE_EVENTS_MASK (LDD_TEventMask)(LDD_TIMERUNIT_ON_COUNTER_RESTART) + +/* Internal method prototypes */ +/* +** =================================================================== +** Method : TU1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr) +{ + TU1_TDeviceData *DeviceDataPrv; + + if (PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID] == NULL) { + /* Allocate device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->InitCntr = 1U; /* First initialization */ + } + else { + /* Memory is already allocated */ + DeviceDataPrv = (TU1_TDeviceDataPtr) PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID]; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->InitCntr++; /* Increment counter of initialization */ + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ + } + /* Interrupt vector(s) allocation */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_FTM0__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC6: FTM0=1 */ + SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; + /* FTM0_MODE: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FAULTIE=0,FAULTM=0,CAPTEST=0,PWMSYNC=0,WPDIS=1,INIT=0,FTMEN=0 */ + FTM0_MODE = (FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK); /* Set up mode register */ + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=0,PS=0 */ + FTM0_SC = (FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00)); /* Clear status and control register */ + /* FTM0_CNTIN: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,INIT=0 */ + FTM0_CNTIN = FTM_CNTIN_INIT(0x00); /* Clear counter initial register */ + /* FTM0_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ + FTM0_CNT = FTM_CNT_COUNT(0x00); /* Reset counter register */ + /* FTM0_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C0SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C1SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C2SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C2SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C3SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C3SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C4SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C4SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C5SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C5SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C6SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C6SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C7SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C7SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0x5DBF */ + FTM0_MOD = FTM_MOD_MOD(0x5DBF); /* Set up modulo register */ + DeviceDataPrv->EnEvents = 0x0100U; /* Enable selected events */ + DeviceDataPrv->Source = FTM_PDD_SYSTEM; /* Store clock source */ + /* NVICIP25: PRI25=0x80 */ + NVICIP25 = NVIC_IP_PRI25(0x80); + /* NVICISER0: SETENA|=0x02000000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x02000000); + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=1,CPWMS=0,CLKS=0,PS=0 */ + FTM0_SC = (FTM_SC_TOIE_MASK | FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00)); /* Set up status and control register */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : TU1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_Enable(LDD_TDeviceData *DeviceDataPtr) +{ + TU1_TDeviceData *DeviceDataPrv = (TU1_TDeviceData *)DeviceDataPtr; + + FTM_PDD_SelectPrescalerSource(FTM0_BASE_PTR, DeviceDataPrv->Source); /* Enable the device */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : TU1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(TU1_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + TU1_TDeviceDataPtr DeviceDataPrv = INT_FTM0__BAREBOARD_RTOS_ISRPARAM; + + LDD_TEventMask State = 0U; + + if ((FTM_PDD_GetOverflowInterruptFlag(FTM0_BASE_PTR)) != 0U) { /* Is the overflow interrupt flag pending? */ + State |= LDD_TIMERUNIT_ON_COUNTER_RESTART; /* and set mask */ + } + State &= DeviceDataPrv->EnEvents; /* Handle only enabled interrupts */ + if (State & LDD_TIMERUNIT_ON_COUNTER_RESTART) { /* Is the overflow interrupt flag pending? */ + FTM_PDD_ClearOverflowInterruptFlag(FTM0_BASE_PTR); /* Clear flag */ + TU1_OnCounterRestart(DeviceDataPrv->UserDataPtr); /* Invoke OnCounterRestart event */ + } +} + +/* END TU1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.h new file mode 100644 index 0000000..8627c00 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TU1.h @@ -0,0 +1,220 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : uint16_t +** Input clock source : Internal +** Counter frequency : Auto select +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 500 µs +** Interrupt : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : no +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); +** Enable - LDD_TError TU1_Enable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU1.h +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU1_module TU1 module documentation +** @{ +*/ + +#ifndef __TU1_H +#define __TU1_H + +/* MODULE TU1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ + +#include "FTM_PDD.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __BWUserType_TU1_TValueType +#define __BWUserType_TU1_TValueType + typedef uint16_t TU1_TValueType ; /* Type for data parameters of methods */ +#endif +#define TU1_CNT_INP_FREQ_U_0 0x02DC6C00UL /* Counter input frequency in Hz */ +#define TU1_CNT_INP_FREQ_R_0 48000768.0122882F /* Counter input frequency in Hz */ +#define TU1_CNT_INP_FREQ_COUNT 0U /* Count of predefined counter input frequencies */ +#define TU1_PERIOD_TICKS 0x5DC0UL /* Initialization value of period in 'counter ticks' */ +#define TU1_NUMBER_OF_CHANNELS 0x00U /* Count of predefined channels */ +#define TU1_COUNTER_WIDTH 0x10U /* Counter width in bits */ +#define TU1_COUNTER_DIR DIR_UP /* Direction of counting */ +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define TU1_PRPH_BASE_ADDRESS 0x40038000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define TU1_Init_METHOD_ENABLED /*!< Init method of the component TU1 is enabled (generated) */ +#define TU1_Enable_METHOD_ENABLED /*!< Enable method of the component TU1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define TU1_OnCounterRestart_EVENT_ENABLED /*!< OnCounterRestart event of the component TU1 is enabled (generated) */ + + + +/* +** =================================================================== +** Method : TU1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : TU1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_Enable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : TU1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(TU1_Interrupt); + +/* END TU1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __TU1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.c new file mode 100644 index 0000000..308f65e --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.c @@ -0,0 +1,226 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TimerIntLdd1.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerInt_LDD +** Version : Component 01.018, Driver 01.02, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This TimerInt component implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** This TimerInt component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : TimerIntLdd1 +** Periodic interrupt source : FTM0_MOD +** Counter : FTM0_CNT +** Interrupt service/event : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Interrupt period : 500 µs +** Initialization : +** Enabled in init. code : no +** Auto initialization : yes +** Event mask : +** OnInterrupt : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked TimerUnit : TU1 +** Contents : +** Init - LDD_TDeviceData* TimerIntLdd1_Init(LDD_TUserData *UserDataPtr); +** Enable - LDD_TError TimerIntLdd1_Enable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TimerIntLdd1.c +** @version 01.02 +** @brief +** This TimerInt component implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** This TimerInt component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup TimerIntLdd1_module TimerIntLdd1 module documentation +** @{ +*/ + +/* MODULE TimerIntLdd1. */ + +#include "TI1.h" +#include "TimerIntLdd1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TDeviceData *LinkedDeviceDataPtr; + bool EnUser; /* Enable/Disable device */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} TimerIntLdd1_TDeviceData; + +typedef TimerIntLdd1_TDeviceData *TimerIntLdd1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static TimerIntLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; + +#define AVAILABLE_EVENTS_MASK (LDD_TEventMask)(LDD_TIMERINT_ON_INTERRUPT) +/* Internal method prototypes */ +/* +** =================================================================== +** Method : TimerIntLdd1_Init (component TimerInt_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TimerIntLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + TimerIntLdd1_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->EnUser = FALSE; /* Set the flag "device disabled" */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TimerIntLdd1_ID,DeviceDataPrv); + DeviceDataPrv->LinkedDeviceDataPtr = TU1_Init((LDD_TUserData *)NULL); + if (DeviceDataPrv->LinkedDeviceDataPtr == NULL) { /* Is initialization of TimerUnit unsuccessful? */ + /* Unregistration of the device structure */ + PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_TimerIntLdd1_ID); + /* Deallocation of the device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: Dynamic allocation is simulated, no deallocation code is generated */ + return NULL; /* If so, then the TimerInt initialization is also unsuccessful */ + } + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : TimerIntLdd1_Enable (component TimerInt_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TimerIntLdd1_Enable(LDD_TDeviceData *DeviceDataPtr) +{ + TimerIntLdd1_TDeviceData *DeviceDataPrv = (TimerIntLdd1_TDeviceData *)DeviceDataPtr; + + if (!DeviceDataPrv->EnUser) { /* Is the device disabled by user? */ + DeviceDataPrv->EnUser = TRUE; /* If yes then set the flag "device enabled" */ + (void)TU1_Enable(DeviceDataPrv->LinkedDeviceDataPtr); /* Enable TimerUnit */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : TU1_OnCounterRestart (component TimerInt_LDD) +** +** Description : +** The method services the event of the linked component TU1 and +** eventually invokes event TimerIntLdd1_OnInterrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void TU1_OnCounterRestart(LDD_TUserData *UserDataPtr) +{ + TimerIntLdd1_TDeviceData *DeviceDataPrv = PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TimerIntLdd1_ID]; + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + TimerIntLdd1_OnInterrupt(DeviceDataPrv->UserDataPtr); /* Invoke OnInterrupt event */ +} + +/* END TimerIntLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.h new file mode 100644 index 0000000..c8394d1 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/TimerIntLdd1.h @@ -0,0 +1,206 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TimerIntLdd1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : TimerInt_LDD +** Version : Component 01.018, Driver 01.02, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-08, 12:20, # CodeGen: 26 +** Abstract : +** This TimerInt component implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** This TimerInt component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : TimerIntLdd1 +** Periodic interrupt source : FTM0_MOD +** Counter : FTM0_CNT +** Interrupt service/event : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Interrupt period : 500 µs +** Initialization : +** Enabled in init. code : no +** Auto initialization : yes +** Event mask : +** OnInterrupt : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked TimerUnit : TU1 +** Contents : +** Init - LDD_TDeviceData* TimerIntLdd1_Init(LDD_TUserData *UserDataPtr); +** Enable - LDD_TError TimerIntLdd1_Enable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TimerIntLdd1.h +** @version 01.02 +** @brief +** This TimerInt component implements a periodic interrupt. +** When the component and its events are enabled, the "OnInterrupt" +** event is called periodically with the period that you specify. +** TimerInt supports also changing the period in runtime. +** This TimerInt component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup TimerIntLdd1_module TimerIntLdd1 module documentation +** @{ +*/ + +#ifndef __TimerIntLdd1_H +#define __TimerIntLdd1_H + +/* MODULE TimerIntLdd1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "TU1.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define TimerIntLdd1_PRPH_BASE_ADDRESS 0x40038000U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define TimerIntLdd1_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_TimerIntLdd1_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define TimerIntLdd1_Init_METHOD_ENABLED /*!< Init method of the component TimerIntLdd1 is enabled (generated) */ +#define TimerIntLdd1_Enable_METHOD_ENABLED /*!< Enable method of the component TimerIntLdd1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define TimerIntLdd1_OnInterrupt_EVENT_ENABLED /*!< OnInterrupt event of the component TimerIntLdd1 is enabled (generated) */ + + + +/* +** =================================================================== +** Method : TimerIntLdd1_Init (component TimerInt_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TimerIntLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : TimerIntLdd1_Enable (component TimerInt_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TimerIntLdd1_Enable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : TU1_OnCounterRestart (component TimerInt_LDD) +** +** Description : +** The method services the event of the linked component TU1 and +** eventually invokes event TimerIntLdd1_OnInterrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void TU1_OnCounterRestart(LDD_TUserData *UserDataPtr); + +/* END TimerIntLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __TimerIntLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Tx1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Tx1.c new file mode 100644 index 0000000..df3ae8a --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Tx1.c @@ -0,0 +1,437 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Tx1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : RingBuffer +** Version : Component 01.053, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** This component implements a ring buffer for different integer data type. +** Settings : +** Component name : Tx1 +** Buffer Size : 64 +** Contents : +** Clear - void Tx1_Clear(void); +** Put - uint8_t Tx1_Put(Tx1_ElementType elem); +** Get - uint8_t Tx1_Get(Tx1_ElementType *elemP); +** Peek - uint8_t Tx1_Peek(Tx1_BufSizeType index, Tx1_ElementType *elemP); +** Update - uint8_t Tx1_Update(Tx1_BufSizeType index, Tx1_ElementType *elemP); +** Putn - uint8_t Tx1_Putn(Tx1_ElementType *elem, Tx1_BufSizeType nof); +** Getn - uint8_t Tx1_Getn(Tx1_ElementType *buf, Tx1_BufSizeType nof); +** Compare - uint8_t Tx1_Compare(Tx1_BufSizeType index, Tx1_ElementType *elemP,... +** Delete - uint8_t Tx1_Delete(void); +** NofElements - Tx1_BufSizeType Tx1_NofElements(void); +** NofFreeElements - Tx1_BufSizeType Tx1_NofFreeElements(void); +** Deinit - void Tx1_Deinit(void); +** Init - void Tx1_Init(void); +** +** * Copyright (c) 2014-2018, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file Tx1.h +** @version 01.00 +** @brief +** This component implements a ring buffer for different integer data type. +*/ +/*! +** @addtogroup Tx1_module Tx1 module documentation +** @{ +*/ + +/* MODULE Tx1. */ + +#include "Tx1.h" + +#if Tx1_CONFIG_REENTRANT + #define Tx1_DEFINE_CRITICAL() CS1_CriticalVariable() + #define Tx1_ENTER_CRITICAL() CS1_EnterCritical() + #define Tx1_EXIT_CRITICAL() CS1_ExitCritical() +#else + #define Tx1_DEFINE_CRITICAL() /* nothing */ + #define Tx1_ENTER_CRITICAL() /* nothing */ + #define Tx1_EXIT_CRITICAL() /* nothing */ +#endif +static Tx1_ElementType Tx1_buffer[Tx1_CONFIG_BUF_SIZE]; /* ring buffer */ +static Tx1_BufSizeType Tx1_inIdx; /* input index */ +static Tx1_BufSizeType Tx1_outIdx; /* output index */ +static Tx1_BufSizeType Tx1_inSize; /* size data in buffer */ +/* +** =================================================================== +** Method : Put (component RingBuffer) +** +** Description : +** Puts a new element into the buffer +** Parameters : +** NAME - DESCRIPTION +** elem - New element to be put into the buffer +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Put(Tx1_ElementType elem) +{ + uint8_t res = ERR_OK; + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (Tx1_inSize==Tx1_CONFIG_BUF_SIZE) { + res = ERR_TXFULL; + } else { + Tx1_buffer[Tx1_inIdx] = elem; + Tx1_inIdx++; + if (Tx1_inIdx==Tx1_CONFIG_BUF_SIZE) { + Tx1_inIdx = 0; + } + Tx1_inSize++; + } + Tx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Putn (component RingBuffer) +** +** Description : +** Put a number new element into the buffer. +** Parameters : +** NAME - DESCRIPTION +** * elem - Pointer to new elements to be put into +** the buffer +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Putn(Tx1_ElementType *elem, Tx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Tx1_Put(*elem); + if (res!=ERR_OK) { + break; + } + elem++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : Get (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : +** NAME - DESCRIPTION +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Get(Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (Tx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + *elemP = Tx1_buffer[Tx1_outIdx]; + Tx1_inSize--; + Tx1_outIdx++; + if (Tx1_outIdx==Tx1_CONFIG_BUF_SIZE) { + Tx1_outIdx = 0; + } + } + Tx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Getn (component RingBuffer) +** +** Description : +** Get a number elements into a buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer where to store the +** elements +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Getn(Tx1_ElementType *buf, Tx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Tx1_Get(buf); + if (res!=ERR_OK) { + break; + } + buf++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : NofElements (component RingBuffer) +** +** Description : +** Returns the actual number of elements in the buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Tx1_BufSizeType Tx1_NofElements(void) +{ + return Tx1_inSize; +} + +/* +** =================================================================== +** Method : NofFreeElements (component RingBuffer) +** +** Description : +** Returns the actual number of free elements/space in the +** buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Tx1_BufSizeType Tx1_NofFreeElements(void) +{ + return (Tx1_BufSizeType)(Tx1_CONFIG_BUF_SIZE-Tx1_inSize); +} + +/* +** =================================================================== +** Method : Init (component RingBuffer) +** +** Description : +** Initializes the data structure +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Tx1_Init(void) +{ + Tx1_inIdx = 0; + Tx1_outIdx = 0; + Tx1_inSize = 0; +} + +/* +** =================================================================== +** Method : Clear (component RingBuffer) +** +** Description : +** Clear (empty) the ring buffer. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Tx1_Clear(void) +{ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + Tx1_Init(); + Tx1_EXIT_CRITICAL(); +} + +/* +** =================================================================== +** Method : Peek (component RingBuffer) +** +** Description : +** Returns an element of the buffer without removiing it. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Peek(Tx1_BufSizeType index, Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (index>=Tx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index0) { + res = Tx1_Peek(index, &val); + if (res!=ERR_OK) { /* general failure? */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + if (val!=*elemP) { /* mismatch */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + elemP++; index++; nof--; + } + + return cmpResult; +} + +/* +** =================================================================== +** Method : Deinit (component RingBuffer) +** +** Description : +** Driver de-initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void Tx1_Deinit(void) +{ + ** Function is implemented as macro in the header file +} +*/ +/* +** =================================================================== +** Method : Delete (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Delete(void) +{ + uint8_t res = ERR_OK; + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (Tx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + Tx1_inSize--; + Tx1_outIdx++; + if (Tx1_outIdx==Tx1_CONFIG_BUF_SIZE) { + Tx1_outIdx = 0; + } + } + Tx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Update (component RingBuffer) +** +** Description : +** Updates the data of an element. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Update(Tx1_BufSizeType index, Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (index>=Tx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index> 0x08) & 0xFEU); + USB0_BDTPAGE2 = (uint8_t)((((uint32_t)((uint32_t)&g_Mem[0])) >> 0x10) & 0xFFU); + USB0_BDTPAGE3 = (uint8_t)((((uint32_t)((uint32_t)&g_Mem[0])) >> 0x18) & 0xFFU); + /* USB0_SOFTHLD: CNT=0 */ + USB0_SOFTHLD = USB_SOFTHLD_CNT(0x00); + /* USB0_OTGCTL: DPHIGH=0,??=0,DPLOW=0,DMLOW=0,??=0,OTGEN=0,??=0,??=0 */ + USB0_OTGCTL = 0x00U; + /* USB0_CONTROL: ??=0,??=0,??=0,DPPULLUPNONOTG=0,??=0,??=0,??=0,??=0 */ + USB0_CONTROL = 0x00U; + /* USB0_CTL: TXSUSPENDTOKENBUSY=0,HOSTMODEEN=0,ODDRST=0,USBENSOFEN=1 */ + USB0_CTL = (uint8_t)((USB0_CTL & (uint8_t)~(uint8_t)( + USB_CTL_TXSUSPENDTOKENBUSY_MASK | + USB_CTL_HOSTMODEEN_MASK | + USB_CTL_ODDRST_MASK + )) | (uint8_t)( + USB_CTL_USBENSOFEN_MASK + )); +} + +/* +** ################################################################### +** +** The interrupt service routine(s) must be implemented +** by user in one of the following user modules. +** +** If the "Generate ISR" option is enabled, Processor Expert generates +** ISR templates in the CPU event module. +** +** User modules: +** main.c +** Events.c +** +** ################################################################### +PE_ISR(USB_ISR) +{ +// NOTE: The routine should include actions to clear the appropriate +// interrupt flags. +// +} +*/ + + +/* END USB0. */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/USB0.h b/Projects/tinyK20_SolderDispenser/Generated_Code/USB0.h new file mode 100644 index 0000000..aac97dc --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/USB0.h @@ -0,0 +1,279 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : USB0.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Init_USB_OTG +** Version : Component 01.004, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-05-28, 13:34, # CodeGen: 0 +** Abstract : +** This file implements the USB_OTG (USB0) module initialization +** according to the Peripheral Initialization settings, and +** defines interrupt service routines prototypes. +** Settings : +** Component name : USB0 +** Device : USB0 +** Settings : +** Clock gate : Enabled +** Clock settings : +** Clock divider : +** Clock divider source : PLL/FLL clock +** Clock divider input frequency : 96 MHz +** Clock divider fraction : multiply by 1 +** Clock divider divisor : divide by 2 +** Module clock source : Clock divider output +** Module clock frequency : 48 MHz +** Pull-up/pull-down settings : +** Weak pulldowns : Enabled +** Pull-up/pull-down control : Mode dependent +** D+ pull-up : Disabled +** D+ pull-down : Disabled +** D- pull-down : Disabled +** D+ pull-up for non-OTG mode : Disabled +** Endpoints : +** EP0 : Disabled +** Direct low speed : Disabled +** Retry : Enabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP1 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP2 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP3 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP4 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP5 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP6 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP7 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP8 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP9 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP10 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP11 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP12 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP13 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP14 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** EP15 : Disabled +** Setup transfers : Enabled +** Handshake : Disabled +** Rx transfer : Disabled +** Tx transfer : Disabled +** Force stall : Disabled +** Buffer descriptor table : +** External object declaration : extern uint8_t g_Mem[]; +** Address : ((uint32_t)&g_Mem[0]) +** SOF threshold : 0 +** Pins : +** Alternate clock source : Disabled +** SOF output : Disabled +** Data plus : Enabled +** Pin : USB0_DP +** Pin signal : +** Data minus : Enabled +** Pin : USB0_DM +** Pin signal : +** Interrupts : +** USB : +** Interrupt : INT_USB0 +** Interrupt request : Disabled +** Interrupt priority : 0 (Highest) +** ISR Name : USB_ISR +** Stall : Enabled +** Attach : Enabled +** Resume : Enabled +** Sleep : Enabled +** Token OK : Enabled +** Start of frame : Enabled +** Error interrupt : Enabled +** USB reset : Enabled +** Asynchronous Resume interrupt : Enabled +** Error interrupts : +** Bit stuff error : Disabled +** DMA error : Disabled +** Bus turnaround timeout : Disabled +** Data length error : Disabled +** CRC16 error : Disabled +** CRC5 or EOF : Disabled +** PID error : Disabled +** OTG interrupts : +** ID pin changed : Disabled +** 1 ms interrupt : Disabled +** Line stage change : Disabled +** Session valid : Disabled +** "B" session end : Disabled +** "A" bus valid : Disabled +** Initialization : +** Mode : Device +** USB transceiver suspend state : Enabled +** Call Init method : yes +** Contents : +** Init - void USB0_Init(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file USB0.h +** @version 01.04 +** @brief +** This file implements the USB_OTG (USB0) module initialization +** according to the Peripheral Initialization settings, and +** defines interrupt service routines prototypes. +*/ +/*! +** @addtogroup USB0_module USB0 module documentation +** @{ +*/ + +#ifndef USB0_H_ +#define USB0_H_ + +/* MODULE USB0. */ + +/* Including shared modules, which are used in the whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +#include "Cpu.h" + +/* Peripheral base address parameter */ +#define USB0_DEVICE USB0_BASE_PTR + + +/* +** =================================================================== +** Method : USB0_Init (component Init_USB_OTG) +** Description : +** This method initializes registers of the USB_OTG module +** according to the Peripheral Initialization settings. +** Call this method in user code to initialize the module. By +** default, the method is called by PE automatically; see "Call +** Init method" property of the component for more details. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void USB0_Init(void); +/* +** =================================================================== +** The interrupt service routine must be implemented by user in one +** of the user modules (see USB0.c file for more information). +** =================================================================== +*/ +PE_ISR(USB_ISR); + + +/* END USB0. */ +#endif /* #ifndef __USB0_H_ */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.c new file mode 100644 index 0000000..5907ce1 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.c @@ -0,0 +1,175 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : USB1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FSL_USB_Stack +** Version : Component 01.054, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** This component implements a wrapper to the FSL USB Stack. +** Settings : +** Component name : USB1 +** Freescale USB Stack Version : v4.1.1 +** SDK : MCUC1 +** Device Class : CDC Device +** CDC Device : Enabled +** CDCDevice : FSL_USB_CDC_Device +** CDC Host : Disabled +** HID Keyboard Device : Disabled +** HID Joystick Device : Disabled +** HID Mouse Device : Disabled +** MSD Device : Disabled +** MSD Host : Disabled +** Initialization : +** Init USB Function : USB0_Init +** Inherited USB Init : Enabled +** USB Init : Init_USB_OTG_VAR0 +** Initialization : +** Use USB Stack Inititalization : yes +** Call Init Method : yes +** Contents : +** Deinit - uint8_t USB1_Deinit(void); +** Init - uint8_t USB1_Init(void); +** +** * Original USB Stack: (c) Copyright Freescale, all rights reserved, 2013-2015. +** * See separate licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file USB1.h +** @version 01.00 +** @brief +** This component implements a wrapper to the FSL USB Stack. +*/ +/*! +** @addtogroup USB1_module USB1 module documentation +** @{ +*/ + +/* MODULE USB1. */ + +#include "USB1.h" +#include "derivative.h" /* include peripheral declarations */ +#include "types.h" /* Contains User Defined Data Types */ + +/* +** =================================================================== +** Method : USB1_usb_int_dis (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void USB1_usb_int_dis(void) +{ + /* Kinetis K20D50 */ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + NVIC_DisableIRQ(USB0_IRQn); +#else + NVICISER1 = (1<<3); /* Enable interrupts from USB module (Interrupt Set-Enable Register) */ +#endif +} + +/* +** =================================================================== +** Method : USB1_usb_int_en (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void USB1_usb_int_en(void) +{ + /* Kinetis K20D50 */ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + NVIC_ClearPendingIRQ(USB0_IRQn); + NVIC_EnableIRQ(USB0_IRQn); +#else + NVICICPR1 = (1<<3); /* Clear any pending interrupts on USB (Interrupt Clear-Pending Register) */ + NVICISER1 = (1<<3); /* Enable interrupts from USB module (Interrupt Set-Enable Register) */ +#endif +} + +/* +** =================================================================== +** Method : Deinit (component FSL_USB_Stack) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t USB1_Deinit(void) +{ + uint8_t err; + + USB1_usb_int_dis(); /* disable USB interrupts */ + /* Initialize the USB interface */ + err = CDC1_Deinit(); + if(err != ERR_OK) { + /* Error deinitializing USB Class */ + return ERR_FAILED; + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : Init (component FSL_USB_Stack) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t USB1_Init(void) +{ + uint8_t err; + + /* Initialize the USB interface */ + err = CDC1_Init(); + if(err != ERR_OK) { + /* Error initializing USB Class */ + return ERR_FAILED; + } + USB1_usb_int_en(); + return ERR_OK; +} + +/* END USB1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.h new file mode 100644 index 0000000..2b5f0a8 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1.h @@ -0,0 +1,169 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : USB1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : FSL_USB_Stack +** Version : Component 01.054, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** This component implements a wrapper to the FSL USB Stack. +** Settings : +** Component name : USB1 +** Freescale USB Stack Version : v4.1.1 +** SDK : MCUC1 +** Device Class : CDC Device +** CDC Device : Enabled +** CDCDevice : FSL_USB_CDC_Device +** CDC Host : Disabled +** HID Keyboard Device : Disabled +** HID Joystick Device : Disabled +** HID Mouse Device : Disabled +** MSD Device : Disabled +** MSD Host : Disabled +** Initialization : +** Init USB Function : USB0_Init +** Inherited USB Init : Enabled +** USB Init : Init_USB_OTG_VAR0 +** Initialization : +** Use USB Stack Inititalization : yes +** Call Init Method : yes +** Contents : +** Deinit - uint8_t USB1_Deinit(void); +** Init - uint8_t USB1_Init(void); +** +** * Original USB Stack: (c) Copyright Freescale, all rights reserved, 2013-2015. +** * See separate licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file USB1.h +** @version 01.00 +** @brief +** This component implements a wrapper to the FSL USB Stack. +*/ +/*! +** @addtogroup USB1_module USB1 module documentation +** @{ +*/ + +#ifndef __USB1_H +#define __USB1_H + +/* MODULE USB1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "USB1config.h" /* configuration */ + +/* Include inherited components */ +#include "MCUC1.h" +#include "CDC1.h" +#include "USB0.h" + +#include /* for size_t */ + +/* Interfaces/wrappers to the CDC device class, needed for Shell if using default serial/connection to USB (CDC): */ +#define USB1_SendString CDC1_SendString +#define USB1_RecvChar CDC1_GetChar +#define USB1_SendChar CDC1_SendChar +#define USB1_GetCharsInRxBuf CDC1_GetCharsInRxBuf +#define USB1_DATA_BUFF_SIZE CDC1_DATA_BUFF_SIZE /* data buffer size as specified in the properties */ + + +#include "Cpu.h" + + +#ifndef __BWUserType_USB1_TComData +#define __BWUserType_USB1_TComData + typedef uint8_t USB1_TComData ; /* User type for communication data type. */ +#endif + + +#define USB1_USB_ERR_SEND 1 /* Error while sending */ +#define USB1_USB_ERR_BUSOFF 2 /* Bus not ready */ +#define USB1_USB_ERR_INIT 3 /* USB initialization error */ +#define USB1_USB_ERR_TX_CHAR 4 /* Error sending character */ +#define USB1_USB_ERR_TX_STRING 5 /* Error sending string */ +#define USB1_USB_ERR_CHECKED_TXFULL 6 /* Error during sending a checked block */ +#define USB1_USB_ERR_RECEIVE 7 /* Error while starting a receive transaction */ +#define USB1_USB_ERR_DEINIT 8 /* USB deinitialization error */ + +uint8_t USB1_Init(void); +/* +** =================================================================== +** Method : Init (component FSL_USB_Stack) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +void USB1_usb_int_dis(void); +/* +** =================================================================== +** Method : USB1_usb_int_dis (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void USB1_usb_int_en(void); +/* +** =================================================================== +** Method : USB1_usb_int_en (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t USB1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FSL_USB_Stack) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END USB1. */ + +#endif +/* ifndef __USB1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/USB1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1config.h new file mode 100644 index 0000000..69f372b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/USB1config.h @@ -0,0 +1,7 @@ +#ifndef __USB1_CONFIG_H +#define __USB1_CONFIG_H + +/* no configuration supported yet */ + +#endif /* __USB1_CONFIG_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/USB_Config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/USB_Config.h new file mode 100644 index 0000000..aa45428 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/USB_Config.h @@ -0,0 +1,211 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file USB_Config.h + * + * @author B14088 + * + * @version + * + * @date Oct 31, 2010 + * + * @brief + *****************************************************************************/ + +#ifndef USB_CONFIG_H_ +#define USB_CONFIG_H_ + +/*****************************************************************************/ +/* Includes Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Typedef Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Function's Prototypes */ +/*****************************************************************************/ +/* CDC class services */ +extern void USB_Class_CDC_Service_Dic_Bulk_In (PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_Class_CDC_Service_Dic_Bulk_Out(PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_Class_CDC_Service_Cic_Notify(PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event); + +/*****************************************************************************/ +/* Defines & Macros Section */ +/*****************************************************************************/ + +#define REMOTE_WAKEUP_SUPPORT (TRUE) + +/* CDC specific configuration parameters */ +#define DATA_CLASS_SUPPORT (TRUE) +#define CIC_NOTIF_ELEM_SUPPORT (TRUE) /* Mandatory */ +#define DIC_ISOCHRONOUS_SETTING (FALSE) +#define IMPLEMENT_QUEUING (FALSE) + +/* Hardware components configuration */ +#define USB_HW_VREG_EN TRUE +#define USB_HW_PU_EN TRUE + +/* Event callbacks assignation */ +#define USB_EP0_CALLBACK USB_Control_Service + +#if DIC_ISOCHRONOUS_SETTING +#define USB_EP1_CALLBACK USB_Class_CDC_Service_Dic_Iso_In +#define USB_EP2_CALLBACK USB_Class_CDC_Service_Dic_Iso_Out +#else +#define USB_EP1_CALLBACK USB_Class_CDC_Service_Dic_Bulk_In +#define USB_EP2_CALLBACK USB_Class_CDC_Service_Dic_Bulk_Out +#endif + +#define USB_EP3_CALLBACK USB_Class_CDC_Service_Cic_Notify +#define USB_EP4_CALLBACK USB_NULL_CALLBACK +#define USB_EP5_CALLBACK USB_NULL_CALLBACK +#define USB_EP6_CALLBACK USB_NULL_CALLBACK +#define USB_EP7_CALLBACK USB_NULL_CALLBACK +#define USB_EP8_CALLBACK USB_NULL_CALLBACK +#define USB_EP9_CALLBACK USB_NULL_CALLBACK +#define USB_EP10_CALLBACK USB_NULL_CALLBACK +#define USB_EP11_CALLBACK USB_NULL_CALLBACK +#define USB_EP12_CALLBACK USB_NULL_CALLBACK +#define USB_EP13_CALLBACK USB_NULL_CALLBACK +#define USB_EP14_CALLBACK USB_NULL_CALLBACK +#define USB_EP15_CALLBACK USB_NULL_CALLBACK + +#define USB_BUS_RESET_CALLBACK USB_Reset_Service +#define USB_SUSPEND_CALLBACK USB_Suspend_Service +#define USB_SOF_CALLBACK USB_Sof_Service +#define USB_RESUME_CALLBACK USB_Resume_Service +#define USB_SLEEP_CALLBACK USB_Suspend_Service +#define USB_SPEED_DETECTION_CALLBACK USB_NULL_CALLBACK +#define USB_ERROR_CALLBACK USB_Error_Service +#define USB_STALL_CALLBACK USB_Stall_Service + +/* Endpoints configuration */ +#define USB_EP0_ENABLE TRUE +#define USB_EP0_DIR EP_CTRL +#define USB_EP0_HSHK TRUE +#define USB_EP0_SIZE 32 /* default 32 */ + +#if DIC_ISOCHRONOUS_SETTING +#define USB_EP1_ENABLE TRUE +#define USB_EP1_DIR USB_DIR_IN +#define USB_EP1_HSHK FALSE +#define USB_EP1_SIZE 32 /* default 64 */ + +#define USB_EP2_ENABLE TRUE +#define USB_EP2_DIR EP_OUT +#define USB_EP2_HSHK FALSE +#define USB_EP2_SIZE 32 /* default 64 */ +#else +#define USB_EP1_ENABLE TRUE +#define USB_EP1_DIR EP_IN +#define USB_EP1_HSHK TRUE +#define USB_EP1_SIZE 32 /* default 32 */ + +#define USB_EP2_ENABLE TRUE +#define USB_EP2_DIR EP_OUT +#define USB_EP2_HSHK TRUE +#define USB_EP2_SIZE 32 /* default 32 */ +#endif + +#define USB_EP3_ENABLE TRUE +#define USB_EP3_DIR EP_IN +#define USB_EP3_HSHK TRUE +#define USB_EP3_SIZE 32 + +#define USB_EP4_ENABLE FALSE +#define USB_EP4_DIR NA +#define USB_EP4_HSHK TRUE +#define USB_EP4_SIZE 0 + +#define USB_EP5_ENABLE FALSE +#define USB_EP5_DIR NA +#define USB_EP5_HSHK TRUE +#define USB_EP5_SIZE 0 + +#define USB_EP6_ENABLE FALSE +#define USB_EP6_DIR NA +#define USB_EP6_HSHK TRUE +#define USB_EP6_SIZE 0 + +#define USB_EP7_ENABLE FALSE +#define USB_EP7_DIR NA +#define USB_EP7_HSHK TRUE +#define USB_EP7_SIZE 0 + +#define USB_EP8_ENABLE FALSE +#define USB_EP8_DIR NA +#define USB_EP8_HSHK TRUE +#define USB_EP8_SIZE 0 + +#define USB_EP9_ENABLE FALSE +#define USB_EP9_DIR NA +#define USB_EP9_HSHK TRUE +#define USB_EP9_SIZE 0 + +#define USB_EP10_ENABLE FALSE +#define USB_EP10_DIR NA +#define USB_EP10_HSHK TRUE +#define USB_EP10_SIZE 0 + +#define USB_EP11_ENABLE FALSE +#define USB_EP11_DIR NA +#define USB_EP11_HSHK TRUE +#define USB_EP11_SIZE 0 + +#define USB_EP12_ENABLE FALSE +#define USB_EP12_DIR NA +#define USB_EP12_HSHK TRUE +#define USB_EP12_SIZE 0 + +#define USB_EP13_ENABLE FALSE +#define USB_EP13_DIR NA +#define USB_EP13_HSHK TRUE +#define USB_EP13_SIZE 0 + +#define USB_EP14_ENABLE FALSE +#define USB_EP14_DIR NA +#define USB_EP14_HSHK TRUE +#define USB_EP14_SIZE 0 + +#define USB_EP15_ENABLE FALSE +#define USB_EP15_DIR NA +#define USB_EP15_HSHK TRUE +#define USB_EP15_SIZE 0 + +/*****************************************************************************/ +/* Extern Variables Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Function Prototypes Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ + +#endif /* USB_CONFIG_H_ */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.c new file mode 100644 index 0000000..f65e865 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.c @@ -0,0 +1,2758 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +/* MODULE UTIL1. */ + +#include "UTIL1.h" +#include /* for rand() */ + +/* Internal method prototypes */ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill); + +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief copy the string src into dst. It performs the same task as strncpy, except + - always terminates the result string. + - does not zero out the remaining part in dst. + Note: dstSize is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to copy +*/ +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + *dst = '\0'; +} + +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Concat the string src into dst. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to add + */ +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the src in the destination */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the ch in the destination */ + if (dstSize > 0) { + *dst++ = ch; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit unsigned number to convert. + */ +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val) +{ + UTIL1_Num16uToStr(dst, dstSize, (uint16_t)val); +} + +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit signed number to convert. + */ +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val) +{ + UTIL1_Num16sToStr(dst, dstSize, (int16_t)val); +} + +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit unsigned number to convert. + */ +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit signed number to convert. + */ +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int16_t)(0x8000)) { /* special case 0x8000/-32768: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-32768"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = (int16_t)(-val); + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : ShiftRightAndFill (component Utility) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill) +{ + signed char i, j; + + j = 0; + while(dst[j] != '\0') { + j++; + } + i = (signed char)nofFill; + if (i==j) { + /* nothing to do, we are done */ + } else if (i>j) { + while (j>=0) { + dst[i] = dst[j]; + i--; j--; + } + while(i>=0) { + dst[i] = fill; + i--; + } + } else { + /* hmmm, not enough space, return what we have, do nothing */ + } +} + +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit unsigned number to add + */ +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val) +{ + unsigned char buf[sizeof("256")]; /* maximum buffer size we need */ + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit signed number to add + */ +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val) +{ + unsigned char buf[sizeof("-128")]; /* maximum buffer size we need */ + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + */ +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + */ +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 8bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 8bit number to add + */ +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num) +{ + unsigned char buf[sizeof("FF")]; /* maximum buffer size we need */ + unsigned char hex; + + buf[2] = '\0'; + hex = (char)(num & 0x0F); + buf[1] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + hex = (char)((num>>4) & 0x0F); + buf[0] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 16bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 16bit number to add + */ +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num) +{ + unsigned char buf[sizeof("FFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[4] = '\0'; + i = 3; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 24bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 24bit number to add + */ +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[6] = '\0'; + i = 5; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 32bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 32bit number to add + */ +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[8] = '\0'; + i = 7; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit number to add + */ +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (unsigned long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + */ +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit signed number to convert. + */ +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int32_t)(0x80000000)) { /* special case 0x80000000/-2147483648: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-2147483648"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = -val; + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit unsigned number to convert. + */ +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ +bool UTIL1_IsLeapYear(uint16_t year) +{ + return ((((year%4)==0) && (year%100)!=0) || (year%400)==0); +} + +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day) +{ + /* see http://klausler.com/new-dayofweek.html */ + static const uint8_t skew[12] = {0,3,3,6,1,4,6,2,5,0,3,5}; + uint16_t sum; + + sum = (uint16_t)(year-1900); + sum += sum/4; + sum %= 7; + if (UTIL1_IsLeapYear(year) && (month==1 || month==2)) { + sum--; + } + sum += day; + sum %= 7; + sum += skew[month-1]; + sum %= 7; + return (uint8_t)sum; /* 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, ... */ +} + +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators) +{ + size_t lenCopied = 0, lenOverread = 0; + bool quoteMode = FALSE; /* quoteMode means the name is surrounded by ". In this mode, only a second single quote " + terminates the string. In !quoteMode a space or a '\0' may also terminate it correctly */ + bool res = ERR_OK; + #define IS_SPACE(ch) ((ch)==' '||(ch)=='\t'||(ch)=='\n'||(ch)=='\v'||(ch)=='\f'||(ch)=='\r') + + if (filename==NULL || (destname!=NULL && maxlen==0)) { + return ERR_FAILED; + } + if (filename[0] == '"') { /* translated mode */ + filename++; /* overread '"' */ + lenOverread++; + quoteMode=TRUE; + } + if (terminators == NULL) { + terminators = ""; + } + for (;;) { + if (quoteMode) { + if (filename[0] == '"') { + filename++; /* overread '"' */ + lenOverread++; + if (filename[0] != '"') { /* quoteMode is terminated by a single quote. A double quote is treated like a single quote and does not terminate it ! */ + break; /* successfully finished with this name */ + } /* else we copy the second quote " */ + } + if (filename[0] == '\0') { /* unexpected 0. stop */ + res = ERR_FAILED; + break; /* error case: no terminating double quote (") was found */ + } + } else { /* copy mode */ + if (IS_SPACE(filename[0]) || filename[0] == '\0' || strchr(terminators, filename[0]) != NULL) { /* !quoteMode is terminated by space, '\0' or by any char in terminators */ + break; + } + } + if (destname != NULL) { + if (lenCopied + 1 < maxlen) { + destname[0] = filename[0]; + destname++; + } else { + destname[0] = '\0'; /* terminate string */ + destname = NULL; /* avoid it to overwrite not allocated space */ + } + } + lenCopied++; + filename++; + } + if (destname != NULL) { + destname[0] = '\0'; + } + if (lenRead != NULL) { + *lenRead = lenCopied+lenOverread; + } + if (lenWritten != NULL) { + *lenWritten = lenCopied + 1; /* additionally a zero byte written */ + } + return res; +} + +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ +/*------------------------------------------------------------------------/ +/ Universal string handler for user console interface +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * This software is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-------------------------------------------------------------------------*/ +#ifdef __HC12__ + #pragma MESSAGE DISABLE C12056 /* message about SP debug info */ +#endif +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res) +{ +/* 123 -5 0x3ff 0b1111 0377 3.25 w " + ^ 1st call returns 123 and next ptr + ^ 2nd call returns -5 and next ptr + ^ 3rd call returns 1023 and next ptr + ^ 4th call returns 15 and next ptr + ^ 5th call returns 255 and next ptr + ^ 6th call returns 3 and next ptr, caller needs to read '.' + ^ 7th call returns 25 and next ptr + ^ 8th call fails and returns ERR_FAILED +*/ + uint32_t val; + uint8_t c, r, s = 0; + + *res = 0; + while (**str==' ') { + (*str)++; /* Skip leading spaces */ + } + c = **str; + if (c == '-') { /* negative? */ + s = 1; + c = *(++(*str)); + } + if (c == '0') { + c = *(++(*str)); + switch (c) { + case 'x': /* hexadecimal */ + r = 16; c = *(++(*str)); + break; + case 'b': /* binary */ + r = 2; c = *(++(*str)); + break; + default: + if (c <= ' ' || c == '.') { + return ERR_OK; /* single zero */ + } + if (c < '0' || c > '9') { + return ERR_FAILED; /* invalid char */ + } + r = 8; /* octal */ + break; + } /* switch */ + } else { + if (c < '0' || c > '9') { + return ERR_FAILED; /* EOL or invalid char */ + } + r = 10; /* decimal */ + } + val = 0; + while (c > ' ' && c != '.') { + if (c >= 'a') c -= 0x20; + c -= '0'; + if (c >= 17) { + c -= 7; + if (c <= 9) return ERR_FAILED; /* invalid char */ + } + if (c >= r) return ERR_FAILED; /* invalid char for current radix */ + val = val * r + c; + c = *(++(*str)); + } /* while */ + if (s) val = 0 - val; /* apply sign if needed */ + *res = (long)val; + return ERR_OK; +} +#ifdef __HC12__ + #pragma MESSAGE DEFAULT C12056 /* message about SP debug info */ +#endif + +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year) +{ + /* precondition: string points to starting of date, e.g. "01.01.10" or "12.5.2010", and date is in format dd.mm.yy or dd.mm.yyyy */ + const unsigned char *p; + + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, day)==ERR_OK + && *day > 0 && *day <= 31 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal8uNumber(&p, month)==ERR_OK + && *month > 0 && *month <= 12 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal16uNumber(&p, year)==ERR_OK + && *year > 0 && *year <= 3000 /* hopefully this is enough :-) */ + ) + { + if (*year < 100) { + *year += 2000; /* transform '10' into '2010' */ + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + *day = 0; + *month = 0; + *year = 0; + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond) +{ + /* precondition: string points to starting of time string, e.g. "03:15:05" or "03:15:05,3" or "03:15:05,17", and time is in format hh:mm:ss[,hh] */ + const unsigned char *p; + #define SCAN_IS_DIGIT(ch) ((ch)>='0'&&(ch)<='9') + + *hour = 0; + *minute = 0; + *second = 0; + *hSecond = 0; + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, hour)==ERR_OK + && *hour <= 24 + && *p==':' + ) + { + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, minute)==ERR_OK + && *minute <= 60 + ) + { + if (*p==':') { /* there is more after the minute */ + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, second)==ERR_OK + && *second <= 60 + ) + { + if (*p==',') { /* we do have either ",z" or ",hh" */ + p++; /* skip ',' */ + if (SCAN_IS_DIGIT(*p)) { + if (SCAN_IS_DIGIT(*(p+1))) { /* ,hh format */ + *hSecond = (uint8_t)((*p-'0')*10 + *(p+1)-'0'); + return ERR_OK; + } else { /* ,z format */ + *hSecond = (uint8_t)((*p-'0')*10); + p++; + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else { + return ERR_FAILED; /* illegal format, not a number, e.g. ",x" */ + } + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else if (*p==' ' || *p=='\0') { /* nothing more after the minute? Assume zero seconds */ + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _8_NOF_DIGITS (3+1) + uint8_t nofDigits = _8_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint8_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_8_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint8_t val8u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal8uNumber(&p, &val8u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int8_t)(-(int8_t)val8u); + } else { + *val = (int8_t)val8u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _16_NOF_DIGITS (5+1) + uint8_t nofDigits = _16_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint16_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_16_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint16_t val16u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal16uNumber(&p, (uint16_t*)&val16u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int16_t)(-(int16_t)val16u); + } else { + *val = (int16_t)val16u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _32_NOF_DIGITS (10+1) + uint8_t nofDigits = _32_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint32_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_32_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint32_t val32u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal32uNumber(&p, &val32u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int32_t)(-(int32_t)val32u); + } else { + *val = (int32_t)val32u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros) +{ + /* scans e.g. "-3445.071" and returns -3445 in integral part, and 71 in fractional part */ + uint8_t res; + const unsigned char *p = *str; + + *integral = 0; + *fractional = 0; + *nofFractionalZeros = 0; + res = UTIL1_ScanDecimal32sNumber(&p, integral); + if (res != ERR_OK) { + return res; + } + if (*p=='.') { + p++; /* skip '.' */ + while (*p=='0') { /* count leading zeros */ + (*nofFractionalZeros)++; + p++; /* skip leading zero */ + } + if (*p>='0' && *p<='9') { /* number */ + res = UTIL1_ScanDecimal32uNumber(&p, fractional); + if (res != ERR_OK) { + return res; + } + } + } + *str = p; /* store parsing pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strcmp(const char *, const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strcmp() function +} +*/ + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strncmp(const char *, const char *, size_t size) +{ + /Method is implemented as macro in the header file as wrapper to the standard strncmp() function +} +*/ + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ +/*** +uint16_t UTIL1_strlen(const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strlen() function +} +*/ + +static bool isHexCharacter(unsigned char ch) { + /* returns TRUE if character is a hexadecimal character */ + return (ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F'); +} + +static uint8_t PreScanHexNumber(const unsigned char **str) { + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (*p!='0') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip '0' */ + if (*p!='x') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip 'x' */ + *str = p; + return ERR_OK; +} + +static uint8_t HexToDec(const unsigned char **p, unsigned char *val) { + /* convert a hexadecimal character into a decimal value */ + unsigned char ch = **p; + + if (ch>='0' && ch<='9') { + *val = (unsigned char)(ch-'0'); + (*p)++; + return ERR_OK; + } else if (ch>='a' && ch<='f') { + *val = (unsigned char)(ch-'a'+10); + (*p)++; + return ERR_OK; + } else if (ch>='A' && ch<='F') { + *val = (unsigned char)(ch-'A'+10); + (*p)++; + return ERR_OK; + } + return ERR_FAILED; +} + +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 8; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint32_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 4; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint16_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number with 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number without 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail) +{ + int i, j; + + i = (int)UTIL1_strlen((char*)str); + j = (int)UTIL1_strlen((char*)tail); + if (j>i) { /* str is smaller than tail */ + return 1; /* cannot match */ + } + /* compare strings */ + while(str[i]==tail[j]) { + i--; + j--; + if (j<0) { + return 0; /* match */ + } + } + return 1; /* !=0 means no match */ +} + +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail) +{ + /* cut the tail from the string */ + size_t strLen, tailLen; + + if (UTIL1_strtailcmp(str, tail)!=0) { /* check if tail is present */ + return ERR_FAILED; /* tail not found */ + } + tailLen = UTIL1_strlen((char*)tail); + strLen = UTIL1_strlen((char*)str); + /* write \0 to cut the tail */ + str[strLen-tailLen] = '\0'; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num) +{ + if (num<0 && (num/100)==0) { /* e.g. -53 ==> write sign, as strcatNum32() below will not know that it is negative */ + UTIL1_chcat(dst, dstSize, '-'); + } + UTIL1_strcatNum32s(dst, dstSize, num/100); + UTIL1_chcat(dst, dstSize, '.'); + if (num<0) { + num = -num; + } + UTIL1_strcatNum16uFormatted(dst, dstSize, (uint16_t)((unsigned)num%100U), '0', 2); +} + +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr) +{ + int16_t i, len; + + len = (int16_t)UTIL1_strlen((char*)subStr); + for (i=0; *str!='\0'; i++, str++) { + if (UTIL1_strncmp((char*)str, (char*)subStr, len)==0) { + return i; /* found */ + } + } + return -1; /* not found */ +} + +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType) +{ + int i; + uint8_t res; + const unsigned char *p; + + if (nofValues<=1) { + return ERR_FAILED; /* need at least two values */ + } + p = *str; + for(i=0;i0) { + *buf++ = *p++; + bufSize--; + } + if (*p!='\"') { + return ERR_FAILED; /* no terminating double quote */ + } else { + p++; /* skip double quote */ + *buf = '\0'; /* terminate buffer */ + } + *cmd = p; /* advance pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize) +{ + uint8_t *p; + size_t nof = 0; + + if (dstSize<2) { + return; /* hmm, really to small for anything than the zero byte? */ + } + p = dst; + while(*p != '\0') { /* find end of string */ + p++; + nof++; + } + UTIL1_strcat(dst+nof, dstSize-nof, src); /* add string */ + dstSize -= nof; + while(*p != '\0' && srcPadSize>0 && dstSize>1) { + p++; + srcPadSize--; + dstSize--; + } + while(srcPadSize>0 && dstSize>1) { + *p++ = padChar; /* add padding char */ + srcPadSize--; + dstSize--; + } + *p = '\0'; /* terminate string */ +} + +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint32_t integral; + uint32_t fractional, shift; + int i; + bool isNeg; + + isNeg = (bool)(val<0); + if (isNeg) { + val = -val; /* make it positive */ + } + integral = (uint32_t)(int32_t)val; + val = val-(float)integral; /* get rid of integral part */ + shift = 1; + for(i=0;i0) { + UTIL1_chcat(dst, dstSize, '.'); + UTIL1_strcatNum32uFormatted(dst, dstSize, fractional, '0', nofFracDigits); + } +} + +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint8_t buf[32]; + + UTIL1_NumFloatToStr(buf, sizeof(buf), val, nofFracDigits); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint16_t UTIL1_GetValue16LE(uint8_t *dataP) +{ + return (uint16_t)((dataP[1]<<8)+(dataP[0])); +} + +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue24LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue32LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[3])<<24)+(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); /* MSB */ +} + +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); +} + +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); + dataP[3] = (uint8_t)((data>>24)&0xff); +} + +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max) +{ +#if 0 /* original Arduino implementation */ + return (x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min; +#else /* improved version, see https://github.com/arduino/Arduino/issues/2466 */ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +#endif +} + +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max) +{ + if (valmax) { + return max; + } + return val; +} + +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ +int32_t UTIL1_random(int32_t min, int32_t max) +{ + int32_t val; + + val = rand()%(max-min+1)+min; + return UTIL1_constrain(val, min, max); +} + +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_randomSetSeed(unsigned int seed) +{ + srand(seed); /* set random number generator seed */ +} + +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max) +{ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +} +#endif + +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes) +{ + if (nofBytes==1) { + UTIL1_strcatNum8Hex(dst, dstSize, (uint8_t)num); + } else if (nofBytes==2) { + UTIL1_strcatNum16Hex(dst, dstSize, (uint16_t)num); + } else if (nofBytes==3) { + UTIL1_strcatNum24Hex(dst, dstSize, num); + } else { /* nofBytes==4 */ + UTIL1_strcatNum32Hex(dst, dstSize, num); + } +} + +/* END UTIL1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.h new file mode 100644 index 0000000..2008393 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1.h @@ -0,0 +1,1422 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +#ifndef __UTIL1_H +#define __UTIL1_H + +/* MODULE UTIL1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "UTIL1config.h" /* configuration */ + +/* other includes needed */ +#include +#include /* for size_t */ +/* special version */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UTIL1_SEP_NUM_TYPE_UINT8, /* uint8_t number type */ + UTIL1_SEP_NUM_TYPE_UINT8_HEX_NO_PREFIX /* uint8_t hex number type, no 0x prefix */ +} UTIL1_SeparatedNumberType; + +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +bool UTIL1_IsLeapYear(uint16_t year); +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ + +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ + +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators); +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year); +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond); +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +#define UTIL1_strcmp(str1, str2) \ + strcmp(str1, str2) + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strncmp(str1, str2, size) \ + strncmp(str1, str2, size) + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strlen(str) \ + strlen(str) + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ + +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ + +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType); +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : ScanDoubleQuotedString (component Utility) +** +** Description : +** Scans a string inside double quotes and returns it without +** the double quotes. +** Parameters : +** NAME - DESCRIPTION +** cmd - Pointer to pointer to string to parse. +** This pointer will be advanced as much as +** parsing is done. +** * buf - Pointer to buffer where to store the string +** bufSize - Size of buffer in bytes +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros); +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize); +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Init(void); +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max); +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ + +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ + +int32_t UTIL1_random(int32_t min, int32_t max); +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ + +void UTIL1_randomSetSeed(unsigned int seed); +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ + +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max); +#endif +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ + +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes); +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ + +/* END UTIL1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __UTIL1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1config.h new file mode 100644 index 0000000..10eda65 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/UTIL1config.h @@ -0,0 +1,13 @@ +/** + * \file + * \brief Configuration header file for Utility + * + * This header file is used to configure settings of the Utility module. + */ + +#ifndef __UTIL1_CONFIG_H +#define __UTIL1_CONFIG_H + +/* no configuration supported yet */ + +#endif /* __UTIL1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/Vectors.c b/Projects/tinyK20_SolderDispenser/Generated_Code/Vectors.c new file mode 100644 index 0000000..439d931 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/Vectors.c @@ -0,0 +1,191 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Vectors.c +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2019-06-03, 13:28, # CodeGen: 14 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Vectors.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Vectors_module Vectors module documentation +** @{ +*/ + + #include "Cpu.h" + #include "LED1.h" + #include "LEDpin1.h" + #include "BitIoLdd1.h" + #include "MCUC1.h" + #include "WAIT1.h" + #include "RTT1.h" + #include "CLS1.h" + #include "UTIL1.h" + #include "XF1.h" + #include "CS1.h" + #include "Step.h" + #include "BitIoLdd2.h" + #include "Dir.h" + #include "BitIoLdd4.h" + #include "MS2.h" + #include "BitIoLdd5.h" + #include "MS1.h" + #include "BitIoLdd6.h" + #include "MotEn.h" + #include "BitIoLdd7.h" + #include "MotSleep.h" + #include "BitIoLdd8.h" + #include "FRTOS1.h" + #include "USB1.h" + #include "CDC1.h" + #include "Tx1.h" + #include "Rx1.h" + #include "USB0.h" + #include "TMOUT1.h" + #include "HF1.h" + #include "TI1.h" + #include "TimerIntLdd1.h" + #include "TU1.h" + #include "KEY1.h" + #include "Inhr1.h" + #include "BitIoLdd9.h" + #include "TRG1.h" + #include "Events.h" + + + /* ISR prototype */ + extern uint32_t __SP_INIT; + extern + #ifdef __cplusplus + "C" + #endif + void __thumb_startup( void ); + + + /*lint -esym(765,__vect_table) Disable MISRA rule (8.10) checking for symbols (__vect_table). Definition of the interrupt vector table placed by linker on a predefined location. */ + /*lint -save -e926 -e927 -e928 -e929 Disable MISRA rule (11.4) checking. Need to explicitly cast pointers to the general ISR for Interrupt vector table */ + + __attribute__ ((section (".vectortable"))) const tVectorTable __vect_table = { /* Interrupt vector table */ + + /* ISR name No. Address Pri Name Description */ + &__SP_INIT, /* 0x00 0x00000000 - ivINT_Initial_Stack_Pointer used by PE */ + { + (tIsrFunc)&__thumb_startup, /* 0x01 0x00000004 - ivINT_Initial_Program_Counter used by PE */ + (tIsrFunc)&Cpu_INT_NMIInterrupt, /* 0x02 0x00000008 -2 ivINT_NMI used by PE */ + (tIsrFunc)&HF1_HardFaultHandler, /* 0x03 0x0000000C -1 ivINT_Hard_Fault used by PE */ + (tIsrFunc)&Cpu_ivINT_Mem_Manage_Fault, /* 0x04 0x00000010 - ivINT_Mem_Manage_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Bus_Fault, /* 0x05 0x00000014 - ivINT_Bus_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Usage_Fault, /* 0x06 0x00000018 - ivINT_Usage_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved7, /* 0x07 0x0000001C - ivINT_Reserved7 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved8, /* 0x08 0x00000020 - ivINT_Reserved8 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved9, /* 0x09 0x00000024 - ivINT_Reserved9 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved10, /* 0x0A 0x00000028 - ivINT_Reserved10 unused by PE */ + (tIsrFunc)&vPortSVCHandler, /* 0x0B 0x0000002C - ivINT_SVCall used by PE */ + (tIsrFunc)&Cpu_ivINT_DebugMonitor, /* 0x0C 0x00000030 - ivINT_DebugMonitor unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved13, /* 0x0D 0x00000034 - ivINT_Reserved13 unused by PE */ + (tIsrFunc)&vPortPendSVHandler, /* 0x0E 0x00000038 - ivINT_PendableSrvReq used by PE */ + (tIsrFunc)&vPortTickHandler, /* 0x0F 0x0000003C - ivINT_SysTick used by PE */ + (tIsrFunc)&Cpu_ivINT_DMA0, /* 0x10 0x00000040 - ivINT_DMA0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA1, /* 0x11 0x00000044 - ivINT_DMA1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA2, /* 0x12 0x00000048 - ivINT_DMA2 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA3, /* 0x13 0x0000004C - ivINT_DMA3 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA_Error, /* 0x14 0x00000050 - ivINT_DMA_Error unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved21, /* 0x15 0x00000054 - ivINT_Reserved21 unused by PE */ + (tIsrFunc)&Cpu_ivINT_FTFL, /* 0x16 0x00000058 - ivINT_FTFL unused by PE */ + (tIsrFunc)&Cpu_ivINT_Read_Collision, /* 0x17 0x0000005C - ivINT_Read_Collision unused by PE */ + (tIsrFunc)&Cpu_ivINT_LVD_LVW, /* 0x18 0x00000060 - ivINT_LVD_LVW unused by PE */ + (tIsrFunc)&Cpu_ivINT_LLW, /* 0x19 0x00000064 - ivINT_LLW unused by PE */ + (tIsrFunc)&Cpu_ivINT_Watchdog, /* 0x1A 0x00000068 - ivINT_Watchdog unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2C0, /* 0x1B 0x0000006C - ivINT_I2C0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_SPI0, /* 0x1C 0x00000070 - ivINT_SPI0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2S0_Tx, /* 0x1D 0x00000074 - ivINT_I2S0_Tx unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2S0_Rx, /* 0x1E 0x00000078 - ivINT_I2S0_Rx unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART0_LON, /* 0x1F 0x0000007C - ivINT_UART0_LON unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART0_RX_TX, /* 0x20 0x00000080 - ivINT_UART0_RX_TX unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART0_ERR, /* 0x21 0x00000084 - ivINT_UART0_ERR unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART1_RX_TX, /* 0x22 0x00000088 - ivINT_UART1_RX_TX unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART1_ERR, /* 0x23 0x0000008C - ivINT_UART1_ERR unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART2_RX_TX, /* 0x24 0x00000090 - ivINT_UART2_RX_TX unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART2_ERR, /* 0x25 0x00000094 - ivINT_UART2_ERR unused by PE */ + (tIsrFunc)&Cpu_ivINT_ADC0, /* 0x26 0x00000098 - ivINT_ADC0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMP0, /* 0x27 0x0000009C - ivINT_CMP0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMP1, /* 0x28 0x000000A0 - ivINT_CMP1 unused by PE */ + (tIsrFunc)&TU1_Interrupt, /* 0x29 0x000000A4 8 ivINT_FTM0 used by PE */ + (tIsrFunc)&Cpu_ivINT_FTM1, /* 0x2A 0x000000A8 - ivINT_FTM1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMT, /* 0x2B 0x000000AC - ivINT_CMT unused by PE */ + (tIsrFunc)&Cpu_ivINT_RTC, /* 0x2C 0x000000B0 - ivINT_RTC unused by PE */ + (tIsrFunc)&Cpu_ivINT_RTC_Seconds, /* 0x2D 0x000000B4 - ivINT_RTC_Seconds unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT0, /* 0x2E 0x000000B8 - ivINT_PIT0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT1, /* 0x2F 0x000000BC - ivINT_PIT1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT2, /* 0x30 0x000000C0 - ivINT_PIT2 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT3, /* 0x31 0x000000C4 - ivINT_PIT3 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PDB0, /* 0x32 0x000000C8 - ivINT_PDB0 unused by PE */ + (tIsrFunc)&USB_ISR, /* 0x33 0x000000CC 0 ivINT_USB0 used by PE */ + (tIsrFunc)&Cpu_ivINT_USBDCD, /* 0x34 0x000000D0 - ivINT_USBDCD unused by PE */ + (tIsrFunc)&Cpu_ivINT_TSI0, /* 0x35 0x000000D4 - ivINT_TSI0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_MCG, /* 0x36 0x000000D8 - ivINT_MCG unused by PE */ + (tIsrFunc)&Cpu_ivINT_LPTimer, /* 0x37 0x000000DC - ivINT_LPTimer unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTA, /* 0x38 0x000000E0 - ivINT_PORTA unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTB, /* 0x39 0x000000E4 - ivINT_PORTB unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTC, /* 0x3A 0x000000E8 - ivINT_PORTC unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTD, /* 0x3B 0x000000EC - ivINT_PORTD unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTE, /* 0x3C 0x000000F0 - ivINT_PORTE unused by PE */ + (tIsrFunc)&Cpu_ivINT_SWI /* 0x3D 0x000000F4 - ivINT_SWI unused by PE */ + } + }; + /*lint -restore Enable MISRA rule (11.4) checking. */ + + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.c new file mode 100644 index 0000000..24742f6 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.c @@ -0,0 +1,350 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Disabled +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +/* MODULE WAIT1. */ + +#include "WAIT1.h" + + +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ +#if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif +#else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif +#endif +#endif +void WAIT1_Wait10Cycles(void) +{ + /* This function will wait 10 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* NOTE: Cortex-M0 and M4 have 1 cycle for a NOP */ + /* Compiler is GNUC */ + __asm ( + /* bl Wait10Cycles() to here: [4] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [4] for overhead */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ + #if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif + #else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif + #endif +#endif +void WAIT1_Wait100Cycles(void) +{ + /* This function will spend 100 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + __asm ( + /* bl to here: [4] */ + "push {r0} \n\t" /* [2] */ + "movs r0, #0 \n\t" /* [1] */ + "loop: \n\t" + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "add r0,#1 \n\t" /* [1] */ + "cmp r0,#9 \n\t" /* [1] */ + "bls loop \n\t" /* [3] taken, [1] not taken */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "pop {r0} \n\t" /* [2] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [10] for overhead */ + " li a5,20 \n\t" + "Loop: \n\t" + " addi a5,a5,-1 \n\t" + " bgtz a5, Loop \n\t" + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitCycles(uint16_t cycles) +{ + /*lint -save -e522 function lacks side effect. */ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter() 100) { + WAIT1_Wait100Cycles(); + counter -= 100; + } + while(counter > 10) { + WAIT1_Wait10Cycles(); + counter -= 10; + } +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitLongCycles(uint32_t cycles) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter()60000) { + WAIT1_WaitCycles(60000); + cycles -= 60000; + } + WAIT1_WaitCycles((uint16_t)cycles); + /*lint -restore */ +#endif +} + +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Waitms(uint16_t ms) +{ + /*lint -save -e522 function lacks side effect. */ + uint32_t msCycles; /* cycles for 1 ms */ + + /* static clock/speed configuration */ + msCycles = WAIT1_NofCyclesMs(1, WAIT1_INSTR_CLOCK_HZ); + while(ms>0) { + WAIT1_WaitLongCycles(msCycles); + ms--; + } + /*lint -restore */ +} +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void WAIT1_WaitOSms(void) +{ + Method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Init(void) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + /* init cycle counter */ + KIN1_InitCycleCounter(); + KIN1_ResetCycleCounter(); + KIN1_EnableCycleCounter(); +#endif +} + +/* END WAIT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.h new file mode 100644 index 0000000..6438edc --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1.h @@ -0,0 +1,258 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Disabled +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +#ifndef __WAIT1_H +#define __WAIT1_H + +/* MODULE WAIT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "WAIT1config.h" /* configuration */ + +/* other includes needed */ +#if WAIT1_CONFIG_USE_RTOS_WAIT + /* include RTOS header files */ + #include "McuRTOS.h" + #include "FreeRTOS.h" /* for vTaskDelay() */ + #include "task.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define WAIT1_INSTR_CLOCK_HZ CPU_CORE_CLK_HZ /* for Kinetis, use core clock as base for instruction execution */ +#else + extern uint32_t SystemCoreClock; /* clock frequency variable defined system_.h of the SDK */ + #define WAIT1_INSTR_CLOCK_HZ SystemCoreClock /* core clock frequency in Hz */ +#endif +#define WAIT1_NofCyclesMs(ms, hz) ((ms)*((hz)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesUs(us, hz) ((us)*(((hz)/1000)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesNs(ns, hz) (((ns)*(((hz)/1000)/1000))/1000) /* calculates the needed cycles based on bus clock frequency */ + +#define WAIT1_WAIT_C(cycles) \ + ( (cycles)<=10 ? \ + WAIT1_Wait10Cycles() \ + : WAIT1_WaitCycles((uint16_t)cycles) \ + ) /*!< wait for some cycles */ + + +void WAIT1_Wait10Cycles(void); +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Wait100Cycles(void); +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitCycles(uint16_t cycles); +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Waitms(uint16_t ms); +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitus(us) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesUs((us),WAIT1_INSTR_CLOCK_HZ)==0)||(us)==0) ? \ + (void)0 : \ + ( ((us)/1000)==0 ? (void)0 : WAIT1_Waitms((uint16_t)((us)/1000))) \ + , (WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)==0) ? (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitns(ns) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesNs((ns), WAIT1_INSTR_CLOCK_HZ)==0)||(ns)==0) ? \ + (void)0 : \ + WAIT1_Waitus((ns)/1000) \ + , (WAIT1_NofCyclesNs((ns)%1000, WAIT1_INSTR_CLOCK_HZ)==0) ? \ + (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesNs(((ns)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ + +#if WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_WaitOSms(ms) vTaskDelay(pdMS_TO_TICKS(ms)) /* use FreeRTOS API */ +#else + #define WAIT1_WaitOSms(ms) WAIT1_Waitms(ms) /* use normal wait */ +#endif +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitLongCycles(uint32_t cycles); +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Init(void); +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END WAIT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __WAIT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1config.h new file mode 100644 index 0000000..566e7a4 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/WAIT1config.h @@ -0,0 +1,27 @@ +/** + * \file + * \brief Configuration header file for Wait + * + * This header file is used to configure settings of the busy waiting module. + */ + +#ifndef __WAIT1_CONFIG_H +#define __WAIT1_CONFIG_H + +#include "MCUC1.h" /* include library configuration */ + +#ifndef WAIT1_CONFIG_USE_CYCLE_COUNTER + #define WAIT1_CONFIG_USE_CYCLE_COUNTER (0 && (MCUC1_CONFIG_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3)) + /*!< 1: Use hardware cycle counter (if present, only on Cortex-M3 or higher), 0: not using hardware cycle counter */ +#endif + +#ifndef WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_CONFIG_USE_RTOS_WAIT (0 && MCUC1_CONFIG_SDK_USE_FREERTOS) + /*!< 1: Use RTOS wait if RTOS is present; 0: use normal busy waiting */ +#endif + +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + #include "KIN1.h" /* include Cortex utility functions */ +#endif + +#endif /* __WAIT1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.c new file mode 100644 index 0000000..18ded02 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.c @@ -0,0 +1,1213 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:40, # CodeGen: 32 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +/* MODULE XF1. */ +/** + * @file xformatc.c + * + * @brief Printf C implementation. + * + * Tested wuth the following operating systems / compilers : + * + * - Visual studio 6 + * - Visual studio 2008 / Windows CE + * - MinGw 32 + * - Linux i686 + * - Linux x86_64 + * - GCC wiith embedded ARM. + * - Linux armel + * - HCS08 with Freescale compiler. + * - SDCC (Z80 and 8051) + * + * @author Mario Viara + * + * + * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) + * This is a free software and is opened for education, research and commercial + * developments under license policy of following terms: + * + * - This is a free software and there is NO WARRANTY. + * - No restriction on use. You can use, modify and redistribute it for personal, + * non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * - Redistributions of source code must retain the above copyright notice. + * + * To contact the author send an email to mario_at_viara.eu + * + */ +#include "XF1.h" + +/** + * Default largest int is long + */ +#ifndef LONG +#define LONG long +#endif + +/** + * Define the double type if not defined + */ +#ifndef DOUBLE +#define DOUBLE double +#endif + + +/** + * Default long long type + */ +#ifndef LONGLONG +#define LONGLONG long long +#endif + + +/** + * Definition to convert integer part of floating point + * number if supported we use the long long type + */ +#if XCFG_FORMAT_LONGLONG +#define FLOAT_LONG LONGLONG +#define FLOAT_VALUE llvalue +#define FLOAT_TYPE FLAG_TYPE_LONGLONG +#else +#define FLOAT_LONG LONG +#define FLOAT_VALUE lvalue +#define FLOAT_TYPE FLAG_TYPE_LONG +#endif + +/** + * Structure with all parameter used + */ +struct param_s +{ + /** + * Buffer for current integer value and for temporary + * double value defined as union to save stack. + */ + union + { + unsigned LONG lvalue; +#if XCFG_FORMAT_LONGLONG + unsigned LONGLONG llvalue; +#endif +#if XCFG_FORMAT_FLOAT + DOUBLE dvalue; +#endif + } values; + + /** + * Pointer to the output buffer + */ + char* out; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point argument + */ + DOUBLE dbl; + + /** + * Integer part of floating point + */ + unsigned FLOAT_LONG iPart; + +#endif + + + /** + * Current length of the output buffer + */ + int length; + + /** + * Field precision + */ + int prec; + + /** + * Field width + */ + int width; + + + /** + * Count the number of char emitted + */ + unsigned count; + + + /** + * Parser flags + */ + unsigned flags; + +#define FLAG_TYPE_INT 0x0000 /* Argument is integer */ +#define FLAG_TYPE_LONG 0x0001 /* Argument is long */ +#define FLAG_TYPE_SIZEOF 0x0002 /* Argument is size_t */ +#define FLAG_TYPE_LONGLONG 0x0003 /* Argument is long long */ +#define FLAG_TYPE_MASK 0x0003 /* Mask for field type */ +#define FLAG_PREC 0x0004 /* Precision set */ +#define FLAG_LEFT 0x0008 /* Left alignment */ +#define FLAG_BLANK 0x0010 /* Blank before positive integer number */ +#define FLAG_PREFIX 0x0020 /* Prefix required */ +#define FLAG_PLUS 0x0040 /* Force a + before positive number */ +#define FLAG_UPPER 0x0080 /* Output in upper case letter */ +#define FLAG_DECIMAL 0x0100 /* Decimal field */ +#define FLAG_INTEGER 0x0200 /* Integer field */ +#define FLAG_MINUS 0x0400 /* Field is negative */ +#define FLAG_VALUE 0x0800 /* Value set */ +#define FLAG_BUFFER 0x1000 /* Buffer set */ + + /** + * Length of the prefix + */ + int prefixlen; + + /* Buffer to store the field prefix */ + char prefix[2]; + + + /** Buffer to store the biggest integer number in binary */ +#if XCFG_FORMAT_LONGLONG + char buffer[sizeof(LONGLONG)*8+1]; +#else + char buffer[sizeof(LONG)*8+1]; +#endif + + /* Radix for ASCII integer conversion */ + unsigned char radix; + + /* char used for padding */ + char pad; + + + /** + * Current state + */ + char state; + +}; + + +/** + * Enum for the internal state machine + */ +enum State +{ + /* Normal state outputting literal */ + ST_NORMAL = 0, + /* Just read % */ + ST_PERCENT = 1, + + /* Just read flag */ + ST_FLAG = 2, + + /* Just read the width */ + ST_WIDTH = 3, + + /* Just read '.' */ + ST_DOT= 4, + + /* Just read the precision */ + ST_PRECIS = 5, + + /* Just read the size */ + ST_SIZE = 6, + + /* Just read the type specifier */ + ST_TYPE = 7 +}; + +/** + * Enum for char class + */ +enum CharClass +{ + /* Other char */ + CH_OTHER = 0, + /* The % char */ + CH_PERCENT = 1, + /* The . char */ + CH_DOT = 2, + /* The * char */ + CH_STAR = 3, + /* The 0 char */ + CH_ZERO = 4, + /* Digit 0-9 */ + CH_DIGIT = 5, + /* Flag chars */ + CH_FLAG = 6, + /* Size chars */ + CH_SIZE = 7, + /* Type chars */ + CH_TYPE = 8 +}; + + + +/** + * String used when %s is a null parameter + */ +static const char ms_null[] = "(null)"; +/* + * String for true value + */ +static const char ms_true[] = "True"; + +/** + * String for false value + */ +static const char ms_false[]= "False"; + + +/* + * Digit values + */ +static const char ms_digits[] = "0123456789abcdef"; + + +/* + * This table contains the next state for all char and it will be + * generate using xformattable.c + */ + +static const unsigned char formatStates[] = +{ + 0x06,0x00,0x00,0x06,0x00,0x01,0x00,0x00, + 0x10,0x00,0x03,0x06,0x00,0x06,0x02,0x10, + 0x04,0x45,0x45,0x45,0x45,0x05,0x05,0x05, + 0x05,0x35,0x30,0x00,0x50,0x60,0x00,0x00, + 0x00,0x20,0x28,0x38,0x50,0x50,0x00,0x00, + 0x00,0x30,0x30,0x30,0x50,0x50,0x00,0x00, + 0x08,0x20,0x20,0x28,0x20,0x20,0x20,0x00, + 0x08,0x60,0x60,0x60,0x60,0x60,0x60,0x00, + 0x00,0x70,0x78,0x78,0x78,0x70,0x78,0x00, + 0x07,0x08,0x00,0x00,0x07,0x00,0x00,0x08, + 0x08,0x00,0x00,0x08,0x00,0x08,0x00,0x00, + 0x08,0x00,0x07 +}; + + + + +/** + * Convert an unsigned value in one string + * + * All parameter are in the passed structure + * + * @param prec - Minimum precision + * @param lvalue - Unsigned value + * @param radix - Radix (Supported values 2/8/10/16) + * + * @param out - Buffer with the converted value. + */ +static void ulong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.lvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.lvalue & 0x01; + param->values.lvalue >>= 1; + break; + + case 8: + digit = param->values.lvalue & 0x07; + param->values.lvalue >>= 3; + break; + + case 16: + digit = param->values.lvalue & 0x0F; + param->values.lvalue >>= 4; + break; + + default: + case 10: + digit = param->values.lvalue % 10; + param->values.lvalue /= 10; + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} + + +#if XCFG_FORMAT_LONGLONG +#ifdef XCFG_FORMAT_LONG_ARE_LONGLONG +#define ullong2a ulong2a +#else +static void ullong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.llvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.llvalue & 0x01; + param->values.llvalue >>= 1; + break; + + case 8: + digit = param->values.llvalue & 0x07; + param->values.llvalue >>= 3; + break; + + case 16: + digit = param->values.llvalue & 0x0F; + param->values.llvalue >>= 4; + break; + + default: + case 10: + digit = param->values.llvalue % 10; + param->values.llvalue /= 10; + + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} +#endif +#endif + +#if 1 /* << EST */ +typedef struct { + char *s; + size_t space; +} StrOutBuffer; + +static void putCharIntoBufMaxLen(void *arg, char c) { + StrOutBuffer *buff = (StrOutBuffer*)arg; + if (buff->space > 0) { + buff->space--; + *(buff->s)++ = c; + } +} + +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args) { + int res = -1; + StrOutBuffer out; + + out.space = max_len; + out.s = buf; + if (max_len <= 1) { + *buf = 0; + return 0; + } else { + out.space--; /* teminal zero*/ + } + res = (int)XF1_xvformat(putCharIntoBufMaxLen, (void *)&out, fmt, args); + *(out.s) = 0; + if (res > 0) { + res = out.s - buf; + } + return res; +} +#endif + +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ +/** + * Printf like using variable arguments. + * + * @param outchar - Pointer to the function to output one new char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param ... - Arguments + * + * @return The number of char emitted. + * + * @see xvformat + */ +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) +{ + va_list list; + unsigned count; + + va_start(list,fmt); + count = XF1_xvformat(outchar,arg,fmt,list); + + va_end(list); + + return count; +} + +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +/** + * We do not want use any library function. + * + * @param s - C string + * @return The length of the string + */ +static unsigned xstrlen(const char *s) +{ + const char *i; + + for (i = s ; *i ; i++) + { + } + + return (unsigned)(i - s); +} + +static unsigned outBuffer(void (*myoutchar)(void *arg,char),void *arg,const char *buffer,int len,unsigned toupper) +{ + unsigned count = 0; + int i; + char c; + + for (i = 0; i < len ; i++) + { + c = buffer[i]; + + if (toupper && (c >= 'a' && c <= 'z')) + { + c -= 'a' - 'A'; + } + + (*myoutchar)(arg,c); + count++; + } + + return count; +} + + +static unsigned outChars(void (*myoutchar)(void *arg,char),void *arg,char ch,int len) +{ + unsigned count= 0; + + while (len-- > 0) + { + (*myoutchar)(arg,ch); + count++; + } + + return count; +} + +#if 1 /* << EST added xsprintf() */ +static void putCharIntoBuf(void *arg, char c) { + char **s = (char **)arg; + *(*s)++ = c; +} + +int xsprintf(char *buf, const char *fmt, va_list args) { + int res; + + res = (int)XF1_xvformat(putCharIntoBuf, (void *)&buf, fmt, args); + *buf = 0; + return res; +} +#endif + +/* + * Lint want declare list as const but list is an obscured pointer so + * the warning is disabled. + */ +/*lint -save -e818 */ + + +/** + * Printf like format function. + * + * General format : + * + * %[width][.precision][flags]type + * + * - width Is the minimum size of the field. + * + * - precision Is the maximum size of the field. + * + * Supported flags : + * + * - l With integer number the argument will be of type long. + * - ll With integer number the argument will be of type long long. + * - Space for positive integer a space will be added before. + * - z Compatible with C99 the argument is size_t (aka sizeof(void *)) + * - + A + sign prefix positive number. + * - # A prefix will be printed (o for octal,0x for hex,0b for binary) + * - 0 Value will be padded with zero (default is spacwe) + * - - Left justify as default filed have rigth justification. + * + * Supported type : + * + * - s Null terminated string of char. + * - S Null terminated string of char in upper case. + * - i Integer number. + * - d Integer number. + * - u Unsigned number. + * - x Unsigned number in hex. + * - X Unsigned number in hex upper case. + * - b Binary number + * - o Octal number + * - p Pointer will be emitted with the prefix -> + * - P Pointer in upper case letter. + * - f Floating point number. + * - B Boolean value printed as True / False. + * + * @param outchar - Pointer to the function to output one char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param args - List parameters. + * + * @return The number of char emitted. + */ +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list _args) +{ + XCFG_FORMAT_STATIC struct param_s param; + int i; + char c; + +#if XCFG_FORMAT_VA_COPY + va_list args; + + va_copy(args,_args); +#else +#define args _args +#endif + + param.count = 0; + param.state = ST_NORMAL; + + while (*fmt) + { + c = *fmt++; + + if (c < ' ' || c > 'z') + i = (int)CH_OTHER; + else + i = formatStates[c - ' '] & 0x0F; + + param.state = formatStates[(i << 3) + param.state] >> 4; + + + switch (param.state) + { + default: + case ST_NORMAL: + (*outchar)(arg,c); + param.count++; + break; + + case ST_PERCENT: + param.flags = param.length = param.prefixlen = param.width = param.prec = 0; + param.pad = ' '; + break; + + case ST_WIDTH: + if (c == '*') + param.width = (int)va_arg(args,int); + else + param.width = param.width * 10 + (c - '0'); + break; + + case ST_DOT: + break; + + case ST_PRECIS: + param.flags |= FLAG_PREC; + if (c == '*') + param.prec = (int)va_arg(args,int); + else + param.prec = param.prec * 10 + (c - '0'); + break; + + case ST_SIZE: + switch (c) + { + default: + break; + case 'z': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_SIZEOF; + break; + + case 'l': +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONG) + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONGLONG; + } + else + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; + + } +#else + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; +#endif + break; + + + } + break; + + case ST_FLAG: + switch (c) + { + default: + break; + case '-': + param.flags |= FLAG_LEFT; + break; + case '0': + param.pad = '0'; + break; + case ' ': + param.flags |= FLAG_BLANK; + break; + case '#': + param.flags |= FLAG_PREFIX; + break; + case '+': + param.flags |= FLAG_PLUS; + break; + } + break; + + case ST_TYPE: + switch (c) + { + default: + param.length = 0; + break; + + /* + * Pointer upper case + */ + case 'P': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Pointer + */ + case 'p': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_INTEGER | FLAG_TYPE_SIZEOF; + param.radix = 16; + param.prec = sizeof(void *) * 2; + param.prefix[0] = '-'; + param.prefix[1] = '>'; + param.prefixlen = 2; + break; + + /* + * Binary number + */ + case 'b': + param.flags |= FLAG_INTEGER; + param.radix = 2; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'b'; + param.prefixlen = 2; + } + break; + + /* + * Octal number + */ + case 'o': + param.flags |= FLAG_INTEGER; + param.radix = 8; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefixlen = 1; + } + break; + + /* + * Hex number upper case letter. + */ + case 'X': + /* no break */ + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Hex number lower case + */ + case 'x': + param.flags |= FLAG_INTEGER; + param.radix = 16; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'x'; + param.prefixlen = 2; + } + break; + + /* + * Integer number radix 10 + */ + case 'd': + case 'i': + param.flags |= FLAG_DECIMAL|FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Unsigned number + */ + case 'u': + param.flags |= FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Upper case string + */ + case 'S': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Normal string + */ + case 's': + param.out = va_arg(args,char *); + if (param.out == 0) + param.out = (char *)ms_null; + param.length = (int)xstrlen(param.out); + break; + + /* + * Upper case char + */ + case 'C': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Char + */ + case 'c': + param.out = param.buffer; + param.buffer[0] = (char)va_arg(args,int); + param.length = 1; + break; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point number + */ + case 'f': + if (!(param.flags & FLAG_PREC)) + { + param.prec = 6; + } + + param.dbl = va_arg(args,DOUBLE); + param.values.dvalue = 0.50; + for (i = 0 ; i < param.prec ; i++) + param.values.dvalue /= 10.0; + + if (param.dbl < 0) + { + param.flags |= FLAG_MINUS; + param.dbl -= param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= (FLOAT_LONG)param.iPart; + param.dbl = - param.dbl; + } + else + { + param.dbl += param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= param.iPart; + } + + + for (i = 0 ;i < param.prec ;i++) + param.dbl *= 10.0; + + param.values.lvalue = (unsigned LONG)param.dbl; + + param.out = param.buffer + sizeof(param.buffer) - 1; + param.radix = 10; + if (param.prec) + { + ulong2a(¶m); + *param.out -- = '.'; + param.length ++; + } + param.flags |= FLAG_INTEGER | FLAG_BUFFER | + FLAG_DECIMAL | FLAG_VALUE | FLOAT_TYPE; + + param.prec = 0; + param.values.FLOAT_VALUE = (unsigned FLOAT_LONG)param.iPart; + break; +#endif + + /** + * Boolean value + */ + case 'B': + if (va_arg(args,int) != 0) + param.out = (char*)ms_true; + else + param.out = (char*)ms_false; + + param.length = (int)xstrlen(param.out); + break; + + + } + + /* + * Process integer number + */ + if (param.flags & FLAG_INTEGER) + { + if (param.prec == 0) + param.prec = 1; + + if (!(param.flags & FLAG_VALUE)) + { + switch (param.flags & FLAG_TYPE_MASK) + { + case FLAG_TYPE_SIZEOF: + param.values.lvalue = (unsigned LONG)va_arg(args,void *); + break; + case FLAG_TYPE_LONG: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,long); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned long); + break; + + case FLAG_TYPE_INT: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,int); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned int); + break; +#if XCFG_FORMAT_LONGLONG + case FLAG_TYPE_LONGLONG: + param.values.llvalue = (LONGLONG)va_arg(args,long long); + break; +#endif + } + + } + + if ((param.flags & FLAG_PREFIX) && param.values.lvalue == 0) + { + param.prefixlen = 0; + } + + + /* + * Manage signed integer + */ + if (param.flags & FLAG_DECIMAL) + { +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + { + if ((LONGLONG)param.values.llvalue < 0) + { + param.values.llvalue = ~param.values.llvalue + 1; + param.flags |= FLAG_MINUS; + } + } + else + { +#endif + if ((LONG)param.values.lvalue < 0) + { + param.values.lvalue = ~param.values.lvalue + 1; + param.flags |= FLAG_MINUS; + + } +#if XCFG_FORMAT_LONGLONG + } +#endif + if (!(param.flags & FLAG_MINUS) && (param.flags & FLAG_BLANK)) + { + param.prefix[0] = ' '; + param.prefixlen = 1; + } + } + + if ((param.flags & FLAG_BUFFER) == 0) + { + param.out = param.buffer + sizeof(param.buffer) - 1; + } + + +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + ullong2a(¶m); + else + ulong2a(¶m); +#else + + ulong2a(¶m); +#endif + param.out++; + + /* + * Check if a sign is required + */ + if (param.flags & (FLAG_MINUS|FLAG_PLUS)) + { + c = param.flags & FLAG_MINUS ? '-' : '+'; + + if (param.pad == '0') + { + param.prefixlen = 1; + param.prefix[0] = c; + } + else + { + *--param.out = c; + param.length++; + } + } + + + } + else + { + if (param.width && param.length > param.width) + { + param.length = param.width; + } + + } + + /* + * Now width contain the size of the pad + */ + param.width -= (param.length + param.prefixlen); + + param.count += outBuffer(outchar,arg,param.prefix,param.prefixlen,param.flags & FLAG_UPPER); + if (!(param.flags & FLAG_LEFT)) + param.count += outChars(outchar,arg,param.pad,param.width); + param.count += outBuffer(outchar,arg,param.out,param.length,param.flags & FLAG_UPPER); + if (param.flags & FLAG_LEFT) + param.count += outChars(outchar,arg,param.pad,param.width); + + } + } + +#if XCFG_FORMAT_VA_COPY + va_end(args); +#endif + + return param.count; +} +/*lint -restore */ + +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsprintf(char *buf, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsprintf(buf, fmt, args); + va_end(args); + return res; +} + + +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsnprintf(buf, max_len, fmt, args); + va_end(args); + return res; +} + +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Deinit(void) +{ + /* nothing needed */ +} + +/* END XF1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.h b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.h new file mode 100644 index 0000000..f70a85c --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1.h @@ -0,0 +1,191 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyK20_SolderDispenser +** Processor : MK20DX128VFT5 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:41, # CodeGen: 28 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +#ifndef __XF1_H +#define __XF1_H + +/* MODULE XF1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "XF1config.h" /* configuration */ + +/* other includes needed */ +#include /* open argument list support */ +#include /* for size_t */ + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ + /* inform the GNU compiler about printf() style functions, so the compiler can check the arguments */ + #define XF1_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#else + #define XF1_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +/* low level functions */ +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args); +int xsprintf(char *buf, const char *fmt, va_list args); + +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ + +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list args); +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +int XF1_xsprintf(char *buf, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(2,3); +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +void XF1_Init(void); +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void XF1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END XF1. */ + +#endif +/* ifndef __XF1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/XF1config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1config.h new file mode 100644 index 0000000..cb73d79 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/XF1config.h @@ -0,0 +1,75 @@ +#ifndef __XF1_CONFIG_H +#define __XF1_CONFIG_H + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_FLOAT 0 /* 1: enable, 0: disable floating format (component property) */ +#endif + + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_STATIC /* static */ /* used for the buffer. WARNING: using 'static' makes it non-reentrant! */ +#endif + +/** + * MSVC use in x64 model IL32P64 architecture so the largest integer + * is not a standard C integer. + */ +#if defined(_MSC_VER) && defined(_M_AMD64) +#define LONG long long +#define XCFG_FORMAT_LONG_ARE_LONGLONG +#endif + + +/** + * SDCC support only float and for now do not support long long + */ +#ifdef __SDCC +#define DOUBLE float +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 0 +#endif +#endif + + +/** + * Define internal parameters as volatile for 8 bit cpu define + * XCFG_FORMAT_STATIC=static to reduce stack usage. + */ +#ifndef XCFG_FORMAT_STATIC + #define XCFG_FORMAT_STATIC +#endif + +/** + * Define XCFG_FORMAT_FLOAT=0 to remove floating point support + */ +#ifndef XCFG_FORMAT_FLOAT +#define XCFG_FORMAT_FLOAT 1 +#endif + +/** + * Detect support for va_copy this macro must be called for example + * in x86_64 machine to adjust the stack frame when an argument of va_list + * is passed over functions. + */ +#ifndef XCFG_FORMAT_VA_COPY +#if defined(__GNUC__) && defined(__x86_64__) +#define XCFG_FORMAT_VA_COPY 1 +#endif + + +#ifndef XCFG_FORMAT_VA_COPY +#define XCFG_FORMAT_VA_COPY 0 +#endif + +#endif + + +/** + * Define to 0 to support long long type (prefix ll) + */ +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 1 +#endif + + +#endif /* __XF1_CONFIG_H */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.c b/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.c new file mode 100644 index 0000000..4676b0d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.c @@ -0,0 +1,354 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +CRCB_t * pxCurrentCoRoutine = NULL; +static UBaseType_t uxTopCoRoutineReadyPriority = 0; +static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) +{ +BaseType_t xReturn; +CRCB_t *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) +{ +TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +CRCB_t *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pxContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) +{ +CRCB_t *pxUnblockedCRCB; +BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + +#endif /* configUSE_CO_ROUTINES == 0 */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.h b/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.h new file mode 100644 index 0000000..a98ccad --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/croutine.h @@ -0,0 +1,721 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/deprecated_definitions.h b/Projects/tinyK20_SolderDispenser/Generated_Code/deprecated_definitions.h new file mode 100644 index 0000000..d869789 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/deprecated_definitions.h @@ -0,0 +1,280 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/derivative.h b/Projects/tinyK20_SolderDispenser/Generated_Code/derivative.h new file mode 100644 index 0000000..fc3807c --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/derivative.h @@ -0,0 +1,15 @@ +#ifndef __DERIVATIVE_USB +#define __DERIVATIVE_USB + +/* Include the derivative-specific header file */ +#if 0 /* << EST */ + #include +#else + #include "Cpu.h" +#endif + +#define USED_PIT0 +#define __MK_xxx_H__ + +#endif + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.c b/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.c new file mode 100644 index 0000000..692288f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.c @@ -0,0 +1,754 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ + +/* The following bit fields convey control information in a task's event list +item value. It is important they don't clash with the +taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if configUSE_16_BIT_TICKS == 1 + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#else + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#endif + +typedef struct EventGroupDef_t +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) + { + EventGroup_t *pxEventBits; + + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticEventGroup_t equals the size of the real + event group structure. */ + volatile size_t xSize = sizeof( StaticEventGroup_t ); + configASSERT( xSize == sizeof( EventGroup_t ) ); + } /*lint !e529 xSize is referenced if configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + /* The user has provided a statically allocated event group - use it. */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + this event group was created statically in case the event group + is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + /* xEventGroupCreateStatic should only ever be called with + pxEventGroupBuffer pointing to a pre-allocated (compile time + allocated) StaticEventGroup_t variable. */ + traceEVENT_GROUP_CREATE_FAILED(); + } + + return pxEventBits; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) + { + EventGroup_t *pxEventBits; + + /* Allocate the event group. Justification for MISRA deviation as + follows: pvPortMalloc() always ensures returned memory blocks are + aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the EventGroup_t structure - which (if you + follow it through) is the alignment requirements of the TickType_t type + (EventBits_t being of TickType_t itself). Therefore, whenever the + stack alignment requirements are greater than or equal to the + TickType_t alignment requirements the cast is safe. In other cases, + where the natural word size of the architecture is less than + sizeof( TickType_t ), the TickType_t variables will be accessed in two + or more reads operations, and the alignment requirements is only that + of each individual read. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note this + event group was allocated statically in case the event group is + later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ + } + + return pxEventBits; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t uxOriginalBitValue, uxReturn; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + the task unblocks, but some compilers mistakenly generate a + warning about uxReturn being returned without being set if the + assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + xTimeoutOccurred = pdTRUE; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + bits it was waiting for were set, it is possible that since it + unblocked another task has set the bits. If this is the case + then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn, uxControlBits = 0; +BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task is going to block to wait for its required bits to be + set. uxControlBits are used to remember the specified behaviour of + this call to xEventGroupWaitBits() - for use when the event bits + unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + some compilers mistakenly generate a warning about the variable + being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + xTimeoutOccurred = pdTRUE; + } + taskEXIT_CRITICAL(); + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ +UBaseType_t uxSavedInterruptStatus; +EventGroup_t const * const pxEventBits = xEventGroup; +EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +ListItem_t *pxListItem, *pxNext; +ListItem_t const *pxListEnd; +List_t const * pxList; +EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + item before removing the task from the event list. The + eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + that is was unblocked due to its required bits matching, rather + than because it timed out. */ + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + used here as the list item may have been removed from the event list + and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +EventGroup_t *pxEventBits = xEventGroup; +const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + it again. */ + vPortFree( pxEventBits ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + ( void ) xTaskResumeAll(); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from +an interrupt. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from +an interrupt. */ +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) +{ +BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if (configUSE_TRACE_FACILITY == 1) + + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) + { + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.h b/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.h new file mode 100644 index 0000000..dc627ea --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/event_groups.h @@ -0,0 +1,758 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
+	// StaticEventGroup_t is a publicly accessible structure that has the same
+	// size and alignment requirements as the real event group structure.  It is
+	// provided as a mechanism for applications to know the size of the event
+	// group (which is dependent on the architecture and configuration file
+	// settings) without breaking the strict data hiding policy by exposing the
+	// real event group internals.  This StaticEventGroup_t variable is passed
+	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
+	// the event group's data structures
+	StaticEventGroup_t xEventGroupBuffer;
+
+	// Create the event group without dynamically allocating any memory.
+	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+   
+ */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; + void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/freertos_tasks_c_additions.h b/Projects/tinyK20_SolderDispenser/Generated_Code/freertos_tasks_c_additions.h new file mode 100644 index 0000000..8b09ef2 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/freertos_tasks_c_additions.h @@ -0,0 +1,138 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* freertos_tasks_c_additions.h Rev. 1.4 */ +#ifndef FREERTOS_TASKS_C_ADDITIONS_H +#define FREERTOS_TASKS_C_ADDITIONS_H + +#include +#if !defined(__HIWARE__) /* << EST */ + #include +#endif + +#if (configUSE_TRACE_FACILITY == 0) +#error "configUSE_TRACE_FACILITY must be enabled" +#endif + +#define FREERTOS_DEBUG_CONFIG_MAJOR_VERSION 1 +#define FREERTOS_DEBUG_CONFIG_MINOR_VERSION 2 + +/* NOTE!! + * Default to a FreeRTOS version which didn't include these macros. FreeRTOS + * v7.5.3 is used here. + */ +#ifndef tskKERNEL_VERSION_BUILD +#define tskKERNEL_VERSION_BUILD 3 +#endif +#ifndef tskKERNEL_VERSION_MINOR +#define tskKERNEL_VERSION_MINOR 5 +#endif +#ifndef tskKERNEL_VERSION_MAJOR +#define tskKERNEL_VERSION_MAJOR 7 +#endif + +/* NOTE!! + * The configFRTOS_MEMORY_SCHEME macro describes the heap scheme using a value + * 1 - 5 which corresponds to the following schemes: + * + * heap_1 - the very simplest, does not permit memory to be freed + * heap_2 - permits memory to be freed, but not does coalescence adjacent free + * blocks. + * heap_3 - simply wraps the standard malloc() and free() for thread safety + * heap_4 - coalesces adjacent free blocks to avoid fragmentation. Includes + * absolute address placement option + * heap_5 - as per heap_4, with the ability to span the heap across + * multiple nonOadjacent memory areas + * heap_6 - reentrant newlib implementation + */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 3 /* thread safe malloc */ +#endif + +#if ((configUSE_HEAP_SCHEME > 6) || (configUSE_HEAP_SCHEME < 1)) /* <= 10) && (tskKERNEL_VERSION_MINOR >= 2) +// Need the portARCH_NAME define +#ifndef portARCH_NAME +#define portARCH_NAME NULL +#endif +#if defined(__GNUC__) +char *const portArch_Name __attribute__((section(".rodata"))) = portARCH_NAME; +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +char *const portArch_Name __attribute__((used)) = portARCH_NAME; +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma required=portArch_Name +char *const portArch_Name = portARCH_NAME; +#endif +#else +char *const portArch_Name = NULL; +#endif // tskKERNEL_VERSION_MAJOR + +#if defined(__GNUC__) + const uint8_t FreeRTOSDebugConfig[] __attribute__((section(".rodata"))) = +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) + const uint8_t FreeRTOSDebugConfig[] __attribute__((used)) = +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma required=FreeRTOSDebugConfig + const uint8_t FreeRTOSDebugConfig[] = +#else /* << EST generic compiler */ + const uint8_t FreeRTOSDebugConfig[] = +#endif +{ + FREERTOS_DEBUG_CONFIG_MAJOR_VERSION, + FREERTOS_DEBUG_CONFIG_MINOR_VERSION, + tskKERNEL_VERSION_MAJOR, + tskKERNEL_VERSION_MINOR, + tskKERNEL_VERSION_BUILD, + configUSE_HEAP_SCHEME, + offsetof(struct tskTaskControlBlock, pxTopOfStack), +#if (tskKERNEL_VERSION_MAJOR > 8) + offsetof(struct tskTaskControlBlock, xStateListItem), +#else + offsetof(struct tskTaskControlBlock, xGenericListItem), +#endif + offsetof(struct tskTaskControlBlock, xEventListItem), + offsetof(struct tskTaskControlBlock, pxStack), + offsetof(struct tskTaskControlBlock, pcTaskName), + offsetof(struct tskTaskControlBlock, uxTCBNumber), + offsetof(struct tskTaskControlBlock, uxTaskNumber), + configMAX_TASK_NAME_LEN, + configMAX_PRIORITIES, +#if (tskKERNEL_VERSION_MAJOR >= 10) && (tskKERNEL_VERSION_MINOR >= 2) + configENABLE_MPU, + configENABLE_FPU, + configENABLE_TRUSTZONE, + configRUN_FREERTOS_SECURE_ONLY, + 0, // 32-bit align + 0, 0, 0, 0 // padding +#else + 0 // pad to 32-bit boundary +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif // FREERTOS_TASKS_C_ADDITIONS_H + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_1.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_1.c new file mode 100644 index 0000000..f540c1d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_1.c @@ -0,0 +1,168 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==1 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * The simplest possible implementation of pvPortMalloc(). Note that this + * implementation does NOT allow allocated memory to be freed again. + * + * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Index into the ucHeap array. */ +static size_t xNextFreeByte = ( size_t ) 0; + +/*-----------------------------------------------------------*/ +static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; +//static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if( portBYTE_ALIGNMENT != 1 ) + { + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + #endif + + vTaskSuspendAll(); + { + if( pucAlignedHeap == NULL ) + { + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + } + + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = pucAlignedHeap + xNextFreeByte; + xNextFreeByte += xWantedSize; + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and + heap_4.c for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; + + /* Force an assert as it is invalid to call this function. */ + configASSERT( pv == NULL ); +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); +} + +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xNextFreeByte = 0; + pucAlignedHeap = NULL; +} +#endif + +#endif /* configUSE_HEAP_SCHEME==1 */ /* << EST */ + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_2.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_2.c new file mode 100644 index 0000000..97febb0 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_2.c @@ -0,0 +1,296 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==2 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block (and so will fragment memory). See heap_4.c for + * an equivalent that does combine adjacent blocks into single larger blocks. + * + * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* + * Initialises the heap structures before their first use. + */ +static void prvHeapInit( void ); + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + + +static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +BlockLink_t *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ +static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +//static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the BlockLink_t structure + at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This unexpected casting is to keep some compilers from issuing + byte alignment warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; + + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* xEnd is used to mark the end of the list of free blocks. */ + xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; + xEnd.pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xEnd.pxNextFreeBlock = NULL; + xEnd.xBlockSize = 0; + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + xHeapHasBeenInitialised = pdFALSE; +} +#endif +#endif /* configUSE_HEAP_SCHEME==2 */ /* << EST */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_3.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_3.c new file mode 100644 index 0000000..5d6a383 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_3.c @@ -0,0 +1,109 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==3 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.0 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Implementation of pvPortMalloc() and vPortFree() that relies on the + * compilers own malloc() and free() implementations. + * + * This file can only be used if the linker is configured to to generate + * a heap memory area. + * + * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn; + + vTaskSuspendAll(); + { + pvReturn = malloc( xWantedSize ); + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + if( pv ) + { + vTaskSuspendAll(); + { + free( pv ); + traceFREE( pv, 0 ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* configUSE_HEAP_SCHEME==3 */ /* << EST */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_4.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_4.c new file mode 100644 index 0000000..3596d8f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_4.c @@ -0,0 +1,467 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==4 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static unsigned char ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static unsigned char __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#elif( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +#if 0 +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#else /* << EST do not optimize this variable, needed for NXP TAD plugin */ +static const volatile size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#endif + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; +size_t uxAddress; +size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( portBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + pxEnd = NULL; /* force initialization of heap next time a block gets allocated */ + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xFreeBytesRemaining = 0; + xMinimumEverFreeBytesRemaining = 0; + xBlockAllocatedBit = 0; +} +#endif +#endif /* configUSE_HEAP_SCHEME==4 */ /* << EST */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_5.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_5.c new file mode 100644 index 0000000..475f185 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_5.c @@ -0,0 +1,499 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==5 && configSUPPORT_DYNAMIC_ALLOCATION==1) +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() that allows the heap to be defined + * across multiple non-contigous blocks and combines (coalescences) adjacent + * memory blocks as they are freed. + * + * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative + * implementations, and the memory management pages of http://www.FreeRTOS.org + * for more information. + * + * Usage notes: + * + * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). + * pvPortMalloc() will be called if any task objects (tasks, queues, event + * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be + * called before any other objects are defined. + * + * vPortDefineHeapRegions() takes a single parameter. The parameter is an array + * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as + * + * typedef struct HeapRegion + * { + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * } HeapRegion_t; + * + * The array is terminated using a NULL zero sized region definition, and the + * memory regions defined in the array ***must*** appear in address order from + * low address to high address. So the following is a valid example of how + * to use the function. + * + * HeapRegion_t xHeapRegions[] = + * { + * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 + * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 + * { NULL, 0 } << Terminates the array. + * }; + * + * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). + * + * Note 0x80000000 is the lower address so appears in the array first. + * + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); + + vTaskSuspendAll(); + { + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) +{ +BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; +size_t xAlignedHeap; +size_t xTotalRegionSize, xTotalHeapSize = 0; +BaseType_t xDefinedRegions = 0; +size_t xAddress; +const HeapRegion_t *pxHeapRegion; + + /* Can only call once! */ + configASSERT( pxEnd == NULL ); + + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + + while( pxHeapRegion->xSizeInBytes > 0 ) + { + xTotalRegionSize = pxHeapRegion->xSizeInBytes; + + /* Ensure the heap region starts on a correctly aligned boundary. */ + xAddress = ( size_t ) pxHeapRegion->pucStartAddress; + if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + xAddress += ( portBYTE_ALIGNMENT - 1 ); + xAddress &= ~portBYTE_ALIGNMENT_MASK; + + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; + } + + xAlignedHeap = xAddress; + + /* Set xStart if it has not already been set. */ + if( xDefinedRegions == 0 ) + { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + } + else + { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); + + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( xAddress > ( size_t ) pxEnd ); + } + + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; + + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + xAddress = xAlignedHeap + xTotalRegionSize; + xAddress -= xHeapStructSize; + xAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = ( BlockLink_t * ) xAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; + pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if( pxPreviousFreeBlock != NULL ) + { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } + + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + + /* Move onto the next HeapRegion_t structure. */ + xDefinedRegions++; + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + } + + xMinimumEverFreeBytesRemaining = xTotalHeapSize; + xFreeBytesRemaining = xTotalHeapSize; + + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +/*-----------------------------------------------------------*/ + +#endif /* configUSE_HEAP_SCHEME==5 */ /* << EST */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.c b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.c new file mode 100644 index 0000000..c161cf5 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.c @@ -0,0 +1,200 @@ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) +/** + * \file heap_useNewlib.c + * \brief Wrappers required to use newlib malloc-family within FreeRTOS. + * + * \par Overview + * Route FreeRTOS memory management functions to newlib's malloc family. + * Thus newlib and FreeRTOS share memory-management routines and memory pool, + * and all newlib's internal memory-management requirements are supported. + * + * \author Dave Nadler + * \date 1-July-2017 + * + * \see https://sourceware.org/newlib/libc.html#Reentrancy + * \see https://sourceware.org/newlib/libc.html#malloc + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fenv_005flock + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fmalloc_005flock + * \see https://sourceforge.net/p/freertos/feature-requests/72/ + * \see http://www.billgatliff.com/newlib.html + * \see http://wiki.osdev.org/Porting_Newlib + * \see http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html + * + * + * \copyright + * (c) Dave Nadler 2017, All Rights Reserved. + * Web: http://www.nadler.com + * email: drn@nadler.com + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Use or redistributions of source code must retain the above copyright notice, + * this list of conditions, ALL ORIGINAL COMMENTS, and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include // maps to newlib... +#include // mallinfo... +#include // ENOMEM + +#include "freeRTOS.h" // defines public interface we're implementing here +#if !defined(configUSE_NEWLIB_REENTRANT) || (configUSE_NEWLIB_REENTRANT!=1) + #warning "#define configUSE_NEWLIB_REENTRANT 1 // Required for thread-safety of newlib sprintf, strtok, etc..." + // If you're *really* sure you don't need FreeRTOS's newlib reentrancy support, remove this warning... +#endif +#include "task.h" + +// ================================================================================================ +// External routines required by newlib's malloc (sbrk/_sbrk, __malloc_lock/unlock) +// ================================================================================================ + +#if 0 // suggested minimal implementation from https://sourceware.org/newlib/libc.html#Syscalls: + // sbrk: Increase program data space. As malloc and related functions depend on this, + // it is useful to have a working implementation. The following suffices for a standalone system; + // it exploits the symbol _end automatically defined by the GNU linker. + caddr_t sbrk(int incr) { + extern char _end; /* Defined by the linker */ + static char *heap_end; + char *prev_heap_end; + if (heap_end == 0) { + heap_end = &_end; + } + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) { + write (1, "Heap and stack collision\n", 25); + abort (); + } + heap_end += incr; + return (caddr_t) prev_heap_end; + } +#endif +#if 0 // Freescale implementation + caddr_t _sbrk(int incr) + { + extern char end __asm("end"); + extern char heap_limit __asm("__HeapLimit"); + static char *heap_end; + char *prev_heap_end; + if (heap_end == NULL) + heap_end = &end; + prev_heap_end = heap_end; + if (heap_end + incr > &heap_limit) + { + errno = ENOMEM; + return (caddr_t)-1; + } + heap_end += incr; + return (caddr_t)prev_heap_end; + } +#endif + +#ifndef NDEBUG + static int totalBytesProvidedBySBRK = 0; +#endif +extern char configLINKER_HEAP_BASE_SYMBOL, configLINKER_HEAP_LIMIT_SYMBOL, configLINKER_HEAP_SIZE_SYMBOL; // make sure to define these symbols in linker command file +static int heapBytesRemaining = (int)&configLINKER_HEAP_SIZE_SYMBOL; // that's (&__HeapLimit)-(&__HeapBase) + +//! sbrk/_sbrk version supporting reentrant newlib (depends upon above symbols defined by linker control file). +char * sbrk(int incr) { + static char *currentHeapEnd = &configLINKER_HEAP_BASE_SYMBOL; + vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started + char *previousHeapEnd = currentHeapEnd; + if (currentHeapEnd + incr > &configLINKER_HEAP_LIMIT_SYMBOL) { + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + #elif 0 + // If you want to alert debugger or halt... + while(1) { __asm("bkpt #0"); }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop forever) + #else + // If you prefer to believe your application will gracefully trap out-of-memory... + _impure_ptr->_errno = ENOMEM; // newlib's thread-specific errno + xTaskResumeAll(); + #endif + return (char *)-1; // the malloc-family routine that called sbrk will return 0 + } + currentHeapEnd += incr; + heapBytesRemaining -= incr; + #ifndef NDEBUG + totalBytesProvidedBySBRK += incr; + #endif + xTaskResumeAll(); + return (char *) previousHeapEnd; +} +//! Synonym for sbrk. +char * _sbrk(int incr) { return sbrk(incr); }; + +void __malloc_lock(struct _reent *p) { vTaskSuspendAll(); }; +void __malloc_unlock(struct _reent *p) { (void)xTaskResumeAll(); }; + +// newlib also requires implementing locks for the application's environment memory space, +// accessed by newlib's setenv() and getenv() functions. +// As these are trivial functions, momentarily suspend task switching (rather than semaphore). +// ToDo: Move __env_lock/unlock to a separate newlib helper file. +void __env_lock() { vTaskSuspendAll(); }; +void __env_unlock() { (void)xTaskResumeAll(); }; + +/// /brief Wrap malloc/malloc_r to help debug who requests memory and why. +/// Add to the linker command line: -Xlinker --wrap=malloc -Xlinker --wrap=_malloc_r +// Note: These functions are normally unused and stripped by linker. +void *__wrap_malloc(size_t nbytes) { + extern void * __real_malloc(size_t nbytes); + void *p = __real_malloc(nbytes); // Solely for debug breakpoint... + return p; +}; +void *__wrap__malloc_r(void *reent, size_t nbytes) { + extern void * __real__malloc_r(size_t nbytes); + void *p = __real__malloc_r(nbytes); // Solely for debug breakpoint... + return p; +}; + + +// ================================================================================================ +// Implement FreeRTOS's memory API using newlib-provided malloc family. +// ================================================================================================ + +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION { + void *p = malloc(xSize); + return p; +} +void vPortFree( void *pv ) PRIVILEGED_FUNCTION { + free(pv); +}; + +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION { + struct mallinfo mi = mallinfo(); + return mi.fordblks + heapBytesRemaining; +} + +// GetMinimumEverFree is not available in newlib's malloc implementation. +// So, no implementation provided: size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +//! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; + +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.txt b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.txt new file mode 100644 index 0000000..e0ddeb9 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/heap_useNewlib.txt @@ -0,0 +1,7 @@ +heap_useNewlib.txt +------------------ + +For details, see +- http://www.nadler.com/embedded/newlibAndFreeRTOS.html +- http://mcuoneclipse.com/2017/07/02/using-freertos-with-newlib-and-newlib-nano + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/hidef.h b/Projects/tinyK20_SolderDispenser/Generated_Code/hidef.h new file mode 100644 index 0000000..aa99b54 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/hidef.h @@ -0,0 +1,60 @@ +/******************************************************/ +/** +* @file hidef.h +* Machine/compiler dependent declarations. +*/ +/*---------------------------------------------------- + Copyright (c) Freescale DevTech + All rights reserved + Do not modify! + *****************************************************/ + +#ifndef _H_HIDEF_ +#define _H_HIDEF_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(__CWCC__) + #pragma gcc_extensions on + + /**** Version for ColFire V1 */ + #include + #include "types.h" + + /*!< Macro to enable all interrupts. */ + #define EnableInterrupts __asm ("CPSIE i") + + /*!< Macro to disable all interrupts. */ + #define DisableInterrupts __asm ("CPSID i") + +#elif defined(__IAR_SYSTEMS_ICC__) + #include + + #define EnableInterrupts __enable_interrupt(); + #define DisableInterrupts __disable_interrupt(); + +#elif defined (__CC_ARM) + #define EnableInterrupts __enable_irq(); + #define DisableInterrupts __disable_irq(); + +#elif defined (__GNUC__) + #include + #include "types.h" + + /*!< Macro to enable all interrupts. */ + #define EnableInterrupts __asm ("CPSIE i") + + /*!< Macro to disable all interrupts. */ + #define DisableInterrupts __asm ("CPSID i") +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/*****************************************************/ +/* end hidef.h */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/list.c b/Projects/tinyK20_SolderDispenser/Generated_Code/list.c new file mode 100644 index 0000000..d304411 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/list.c @@ -0,0 +1,199 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; + + /* Write known values into the list if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); + listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pxContainer = NULL; + + /* Write known values into the list item if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t * const pxIndex = pxList->pxIndex; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t *pxIterator; +const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert the new list item into the list, sorted in xItemValue order. + + If the list already contains a list item with the same item value then the + new list item should be placed after it. This ensures that TCBs which are + stored in ready lists (all of which have the same xItemValue value) get a + share of the CPU. However, if the xItemValue is the same as the back marker + the iteration loop below will not end. Therefore the value is checked + first, and the algorithm slightly modified if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are + listed below. In addition see https://www.freertos.org/FAQHelp.html for + more tips, and ensure configASSERT() is defined! + https://www.freertos.org/a00110.html#configASSERT + + 1) Stack overflow - + see https://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M + parts where numerically high priority values denote low actual + interrupt priorities, which can seem counter intuitive. See + https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition + of configMAX_SYSCALL_INTERRUPT_PRIORITY on + https://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ + { + /* There is nothing to do here, just iterating to the wanted + insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list +item. */ +List_t * const pxList = pxItemToRemove->pxContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pxContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/list.h b/Projects/tinyK20_SolderDispenser/Generated_Code/list.h new file mode 100644 index 0000000..355ff81 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/list.h @@ -0,0 +1,413 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H + #error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + + /* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + + /* Define macros that will assert if one of the structure members does not + contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/message_buffer.h b/Projects/tinyK20_SolderDispenser/Generated_Code/message_buffer.h new file mode 100644 index 0000000..784fc31 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/message_buffer.h @@ -0,0 +1,800 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. + */ +typedef void * MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
+
+ * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+const size_t xMessageBufferSizeBytes = 100;
+
+    // Create a message buffer that can hold 100 bytes.  The memory used to hold
+    // both the message buffer structure and the messages themselves is allocated
+    // dynamically.  Each message added to the buffer consumes an additional 4
+    // bytes which are used to hold the lengh of the message.
+    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
+
+    if( xMessageBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // message buffer.
+    }
+    else
+    {
+        // The message buffer was created successfully and can now be used.
+    }
+
+
+ * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
+                                                  uint8_t *pucMessageBufferStorageArea,
+                                                  StaticMessageBuffer_t *pxStaticMessageBuffer );
+
+ * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the messages.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the messages within the message
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the message buffer structure.
+StaticMessageBuffer_t xMessageBufferStruct;
+
+void MyFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+
+    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
+                                                 ucBufferStorage,
+                                                 &xMessageBufferStruct );
+
+    // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
+    // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
+    // reference the created message buffer in other message buffer API calls.
+
+    // Other code that uses the message buffer can go here.
+}
+
+
+ * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
+                           const void *pvTxData,
+                           size_t xDataLengthBytes,
+                           TickType_t xTicksToWait );
+
+ *
+ * Sends a discrete message to the message buffer.  The message can be any
+ * length that fits within the buffer's free space, and is copied into the
+ * buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param xTicksToWait The maximum amount of time the calling task should remain
+ * in the Blocked state to wait for enough space to become available in the
+ * message buffer, should the message buffer have insufficient space when
+ * xMessageBufferSend() is called.  The calling task will never block if
+ * xTicksToWait is zero.  The block time is specified in tick periods, so the
+ * absolute time it represents is dependent on the tick frequency.  The macro
+ * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
+ * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
+ * the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The number of bytes written to the message buffer.  If the call to
+ * xMessageBufferSend() times out before there was enough space to write the
+ * message into the message buffer then zero is returned.  If the call did not
+ * time out then xDataLengthBytes is returned.
+ *
+ * Example use:
+
+void vAFunction( MessageBufferHandle_t xMessageBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the message buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the message buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xMessageBufferSend() times out before there was enough
+        // space in the buffer for the data to be written.
+    }
+
+    // Send the string to the message buffer.  Return immediately if there is
+    // not enough space in the buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+}
+
+ * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
+                                  const void *pvTxData,
+                                  size_t xDataLengthBytes,
+                                  BaseType_t *pxHigherPriorityTaskWoken );
+
+ *
+ * Interrupt safe version of the API function that sends a discrete message to
+ * the message buffer.  The message can be any length that fits within the
+ * buffer's free space, and is copied into the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xMessageBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xMessageBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes actually written to the message buffer.  If the
+ * message buffer didn't have enough free space for the message to be stored
+ * then 0 is returned, otherwise xDataLengthBytes is returned.
+ *
+ * Example use:
+
+// A message buffer that has already been created.
+MessageBufferHandle_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the message buffer.
+    xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
+                                            ( void * ) pcStringToSend,
+                                            strlen( pcStringToSend ),
+                                            &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
+                              void *pvRxData,
+                              size_t xBufferLengthBytes,
+                              TickType_t xTicksToWait );
+
+ * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: +
+void vAFunction( MessageBuffer_t xMessageBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive the next message from the message buffer.  Wait in the Blocked
+    // state (so not using any CPU processing time) for a maximum of 100ms for
+    // a message to become available.
+    xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
+                                            ( void * ) ucRxData,
+                                            sizeof( ucRxData ),
+                                            xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+}
+
+ * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) + + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
+                                     void *pvRxData,
+                                     size_t xBufferLengthBytes,
+                                     BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: +
+// A message buffer that has already been created.
+MessageBuffer_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next message from the message buffer.
+    xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) + + +/** + * message_buffer.h +
+size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
+
+ * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) +#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ + +/** + * message_buffer.h +
+ size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
+ 
+ * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_prototypes.h b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_prototypes.h new file mode 100644 index 0000000..900111e --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_prototypes.h @@ -0,0 +1,158 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API functions. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of timers.h API functions. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of event_group.h API functions. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; + + + +#endif /* MPU_PROTOTYPES_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.c b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.c new file mode 100644 index 0000000..f59350b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.c @@ -0,0 +1,1342 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if configENABLE_MPU /* << EST: only compile this module if MPU is actually enabled and supported */ + +/** + * @brief Calls the port specific code to raise the privilege. + * + * @return pdFALSE if privilege was raised, pdTRUE otherwise. + */ +BaseType_t xPortRaisePrivilege( void ) FREERTOS_SYSTEM_CALL; + +/** + * @brief If xRunningPrivileged is not pdTRUE, calls the port specific + * code to reset the privilege, otherwise does nothing. + */ +void vPortResetPrivilege( BaseType_t xRunningPrivileged ); +/*-----------------------------------------------------------*/ + +BaseType_t xPortRaisePrivilege( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged; + + /* Check whether the processor is already privileged. */ + xRunningPrivileged = portIS_PRIVILEGED(); + + /* If the processor is not already privileged, raise privilege. */ + if( xRunningPrivileged != pdTRUE ) + { + portRAISE_PRIVILEGE(); + } + + return xRunningPrivileged; +} +/*-----------------------------------------------------------*/ + +void vPortResetPrivilege( BaseType_t xRunningPrivileged ) +{ + if( xRunningPrivileged != pdTRUE ) + { + portRESET_PRIVILEGE(); + } +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestricted( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestrictedStatic( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskAbortDelay( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + eTaskState eReturn; + + eReturn = eTaskGetState( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspendAll(); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskResumeAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskResumeAll(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ +{ +TickType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ +{ +UBaseType_t uxReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ +{ +char *pcReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTaskGetName( xTaskToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetHandle( pcNameToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskList( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleRunTimeCounter(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHookFunction_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + vPortResetPrivilege( xRunningPrivileged ); + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + configSTACK_DEPTH_TYPE uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetTimeOutState( pxTimeOut ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGenericNotify( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + uint32_t ulReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + ulReturn = ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return ulReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyStateClear( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueSpacesAvailable( xQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + void * xReturn; + + xReturn = xQueueGetMutexHolder( xSemaphore ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutex( ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetMemberHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueUnregisterQueue( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + const char *MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + const char *pcReturn; + + pcReturn = pcQueueGetName( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueDelete( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void *MPU_pvPortMalloc( size_t xSize ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortFree( void *pv ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortFree( pv ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortInitialiseBlocks( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortInitialiseBlocks(); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + size_t MPU_xPortGetFreeHeapSize( void ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxTimerBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void *MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + void * pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTimerGetTimerID( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetTimerID( xTimer, pvNewID ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerIsTimerActive( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetTimerDaemonTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerPendFunctionCall( xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetReloadMode( xTimer, uxAutoReload ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + const char * pcReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTimerGetName( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetPeriod( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetExpiryTime( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreate(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vEventGroupDelete( xEventGroup ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vStreamBufferDelete( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsFull( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReset( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + +/* Functions that the application writer wants to execute in privileged mode +can be defined in application_defined_privileged_functions.h. The functions +must take the same format as those above whereby the privilege state on exit +equals the privilege state on entry. For example: + +void MPU_FunctionName( [parameters ] ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + FunctionName( [parameters ] ); + + vPortResetPrivilege( xRunningPrivileged ); +} +*/ + +#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" +#endif + +#endif /* configENABLE_MPU */ /* << EST: only compile this module if MPU is actually enabled and supported */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.h b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.h new file mode 100644 index 0000000..b65f6b0 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/mpu_wrappers.h @@ -0,0 +1,187 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + /* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + + /* Map standard tasks.h API functions to the MPU equivalents. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelay MPU_vTaskDelay + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define xTaskGetHandle MPU_xTaskGetHandle + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskNotifyWait MPU_xTaskNotifyWait + #define ulTaskNotifyTake MPU_ulTaskNotifyTake + #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + /* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueGenericReset MPU_xQueueGenericReset + + #if( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif + + /* Map standard timer.h API functions to the MPU equivalents. */ + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall + #define pcTimerGetName MPU_pcTimerGetName + #define vTimerSetReloadMode MPU_vTimerSetReloadMode + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #define xTimerGenericCommand MPU_xTimerGenericCommand + + /* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + #define vEventGroupDelete MPU_vEventGroupDelete + + /* Map standard message/stream_buffer.h API functions to the MPU + equivalents. */ + #define xStreamBufferSend MPU_xStreamBufferSend + #define xStreamBufferReceive MPU_xStreamBufferReceive + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferIsFull MPU_xStreamBufferIsFull + #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty + #define xStreamBufferReset MPU_xStreamBufferReset + #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable + #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable + #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + + + /* Remove the privileged function macro, but keep the PRIVILEGED_DATA + macro so applications can place data in privileged access sections + (useful when using statically allocated objects). */ + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define FREERTOS_SYSTEM_CALL + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/port.c b/Projects/tinyK20_SolderDispenser/Generated_Code/port.c new file mode 100644 index 0000000..dc5e9f6 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/port.c @@ -0,0 +1,1704 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * FreeRTOS for 56800EX port by Richy Ye in Jan. 2013. + *----------------------------------------------------------*/ +/* Scheduler includes. */ +#include "FreeRTOS.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portmacro.h" /* for configCPU_FAMILY */ +#include "task.h" +#include "portTicks.h" /* for CPU_CORE_CLK_HZ used in configSYSTICK_CLOCK_HZ */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if MCUC1_CONFIG_NXP_SDK_2_0_USED + #include "fsl_lptmr.h" /* SDK low power timer interface */ + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "LPTMR_PDD.h" /* PDD interface to low power timer */ + #include "SIM_PDD.h" /* PDD interface to system integration module */ + #endif +#endif + +#include "MCUC1.h" /* include SDK and API used */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +#if( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* --------------------------------------------------- */ +/* Let the user override the pre-loading of the initial LR with the address of + prvTaskExitError() in case is messes up unwinding of the stack in the + debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif +/* --------------------------------------------------- */ +/* macros dealing with tick counter */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if !MCUC1_CONFIG_PEX_SDK_USED + /*! \todo */ + #define LPTMR0_BASE_PTR LPTMR0 /* low power timer address base */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LPTMR0_IRQn /* low power timer IRQ number */ + #define ENABLE_TICK_COUNTER() LPTMR_StartTimer(LPTMR0_BASE_PTR); LPTMR_EnableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define DISABLE_TICK_COUNTER() LPTMR_StopTimer(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() LPTMR_StopTimer(LPTMR0_BASE_PTR); LPTMR_DisableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define ACKNOWLEDGE_TICK_ISR() LPTMR_ClearStatusFlags(LPTMR0_BASE_PTR, kLPTMR_TimerCompareFlag); + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define ENABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_ENABLE); LPTMR_PDD_EnableInterrupt(LPTMR0_BASE_PTR) + #define DISABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_DISABLE); LPTMR_PDD_DisableInterrupt(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() DISABLE_TICK_COUNTER() /* CNR is reset when the LPTMR is disabled or counter register overflows */ + #define ACKNOWLEDGE_TICK_ISR() LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR) + #if defined(LDD_ivIndex_INT_LPTimer) /* Earlier version of Processor Expert use this vector name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTimer + #elif defined(LDD_ivIndex_INT_LPTMR0) /* Newer versions (Processor Expert for Kinetis v3.0.1 uses this name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTMR0 + #else + #error "Unknown Low Power Timer Interrupt Number?" + #endif + #endif +#else + #define ENABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT + #define DISABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT + #define RESET_TICK_COUNTER_VAL() portNVIC_SYSTICK_CURRENT_VALUE_REG = 0 /*portNVIC_SYSTICK_LOAD_REG*/ + #define ACKNOWLEDGE_TICK_ISR() /* not needed */ +#endif + +typedef unsigned long TickCounter_t; /* enough for 24 bit Systick */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TICK_NOF_BITS 16 + #define COUNTS_UP 1 /* LPTMR is counting up */ + #if !MCUC1_CONFIG_PEX_SDK_USED + #define SET_TICK_DURATION(val) LPTMR_SetTimerPeriod(LPTMR0_BASE_PTR, val); + #define GET_TICK_DURATION() LPTMR0_BASE_PTR->CNR /*! \todo SDK has no access method for this */ + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_GetCurrentTimerCount(LPTMR0_BASE_PTR) + #else + #define SET_TICK_DURATION(val) LPTMR_PDD_WriteCompareReg(LPTMR0_BASE_PTR, val) + #define GET_TICK_DURATION() LPTMR_PDD_ReadCompareReg(LPTMR0_BASE_PTR) + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_PDD_ReadCounterReg(LPTMR0_BASE_PTR) + #endif +#else + #define TICK_NOF_BITS 24 + #define COUNTS_UP 0 /* SysTick is counting down to zero */ + #define SET_TICK_DURATION(val) portNVIC_SYSTICK_LOAD_REG = val + #define GET_TICK_DURATION() portNVIC_SYSTICK_LOAD_REG + #define GET_TICK_CURRENT_VAL(addr) *(addr)=portNVIC_SYSTICK_CURRENT_VALUE_REG +#endif + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ/configTICK_RATE_HZ) +#else + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_CLOCK_HZ/configTICK_RATE_HZ) +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + unsigned int SEGGER_SYSVIEW_TickCnt; /* tick counter for Segger SystemViewer */ +#endif + +#if configUSE_TICKLESS_IDLE + #define UL_TIMER_COUNTS_FOR_ONE_TICK ((TickCounter_t)(TIMER_COUNTS_FOR_ONE_TICK)) +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define TICKLESS_DISABLE_INTERRUPTS() __asm volatile("cpsid i") /* disable interrupts. Note that the wfi (wait for interrupt) instruction later will still be able to wait for interrupts! */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm volatile("cpsie i") /* re-enable interrupts. */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define TICKLESS_DISABLE_INTERRUPTS() __asm("sei"); /* disable interrupts */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm("cli"); /* re-enable interrupts */ +#else + #define TICKLESS_DISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /* this disables interrupts! Make sure they are re-enabled in vOnPreSleepProcessing()! */ + #define TICKLESS_ENABLE_INTERRUPTS() portENABLE_INTERRUPTS() /* re-enable interrupts */ +#endif + + #if 1 /* using ARM SysTick Timer */ + #if configSYSTICK_USE_LOW_POWER_TIMER + /* using Low Power Timer */ + #if CONFIG_PEX_SDK_USEDMCUC1_CONFIG_PEX_SDK_USED + #define LPTMR_CSR_TCF_MASK 0x80u + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR0_BASE_PTR->CSR&LPTMR_CSR_TCF_MASK)!=0/*! \todo */ /* returns TRUE if tick interrupt had fired */ + #else + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR_PDD_GetInterruptFlag(LPTMR0_BASE_PTR)!=0) /* returns TRUE if tick interrupt had fired */ + #endif + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #else + /* using directly SysTick Timer */ + #define TICK_INTERRUPT_HAS_FIRED() ((portNVIC_SYSTICK_CTRL_REG&portNVIC_SYSTICK_COUNT_FLAG_BIT)!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #endif + #else + /* using global variable to find out if interrupt has fired */ + volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ + #define TICK_INTERRUPT_HAS_FIRED() (portTickCntr!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() portTickCntr=0 + #define TICK_INTERRUPT_FLAG_SET() portTickCntr=1 + #endif +#endif /* configUSE_TICKLESS_IDLE == 1 */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * resolution of the tick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the tick timer is stopped (low + * power functionality only). + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t ulStoppedTimerCompensation = 0; /* number of timer ticks to compensate */ + #define configSTOPPED_TIMER_COMPENSATION 45UL /* number of CPU cycles to compensate. ulStoppedTimerCompensation will contain the number of timer ticks. */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* Flag indicating that the tick counter interval needs to be restored back to + * the normal setting. Used when woken up from a low power mode using the LPTMR. + */ +#if configUSE_TICKLESS_IDLE && configSYSTICK_USE_LOW_POWER_TIMER + static uint8_t restoreTickInterval = 0; /* used to flag in tick ISR that compare register needs to be reloaded */ +#endif + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portINITIAL_FORMAT_VECTOR ((portSTACK_TYPE)0x4000) + #define portINITIAL_STATUS_REGISTER ((portSTACK_TYPE)0x2000) /* Supervisor mode set. */ +#endif + +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Constants required to manipulate the core. + * SysTick register: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html + * Registers first... + */ +#define portNVIC_SYSTICK_CTRL_REG (*((volatile unsigned long *)0xe000e010)) /* SYST_CSR, SysTick Control and Status Register */ +#define portNVIC_SYSTICK_LOAD_REG (*((volatile unsigned long *)0xe000e014)) /* SYST_RVR, SysTick reload value register */ +#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile unsigned long *)0xe000e018)) /* SYST_CVR, SysTick current value register */ +#define portNVIC_SYSTICK_CALIB_VALUE_REG (*((volatile unsigned long *)0xe000e01C)) /* SYST_CALIB, SysTick calibration value register */ +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_COUNT_FLAG_BIT (1UL<<16UL) /* returns 1 if timer counted to 0 since the last read of the register */ +#if configSYSTICK_USE_CORE_CLOCK + #define portNVIC_SYSTICK_CLK_BIT (1UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#else + #define portNVIC_SYSTICK_CLK_BIT (0UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#endif +#define portNVIC_SYSTICK_INT_BIT (1UL<<1UL) /* SysTick interrupt enable bit */ +#define portNVIC_SYSTICK_ENABLE_BIT (1UL<<0UL) /* SysTick enable bit */ + +/* Constants required to manipulate the NVIC: */ +#define portNVIC_INT_CTRL ((volatile unsigned long*)0xe000ed04) /* interrupt control and state register (ICSR) */ +#define portNVIC_PENDSVSET_BIT (1UL<<28UL) /* bit 28 in portNVIC_INT_CTRL (PENDSVSET), see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihfaaha.html */ +#define portNVIC_PENDSVCLEAR_BIT (1UL<<27UL) /* bit 27 in portNVIC_INT_CTRL (PENDSVCLR) */ +#define portNVIC_PEND_SYSTICK_SET_BIT (1UL<<26UL) /* bit 26 in portNVIC_INT_CTRL (PENDSTSET) */ +#define portNVIC_PEND_SYSTICK_CLEAR_BIT (1UL<<25UL) /* bit 25 in portNVIC_INT_CTRL (PENDSTCLR) */ + +#define portNVIC_SYSPRI2 ((volatile unsigned long*)0xe000ed1c) /* system handler priority register 2 (SHPR2), used for SVCall priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SVCALL_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SVCall interrupt (in portNVIC_SYSPRI2) */ + +#define portNVIC_SYSPRI3 ((volatile unsigned long*)0xe000ed20) /* system handler priority register 3 (SHPR3), used for SysTick and PendSV priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SYSTICK_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SysTick interrupt (in portNVIC_SYSPRI3) */ +#define portNVIC_PENDSV_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<16) /* priority of PendableService interrupt (in portNVIC_SYSPRI3) */ + +#define portNVIC_SYSPRI7 ((volatile unsigned long*)0xe000e41c) /* system handler priority register 7, PRI_28 is LPTMR */ +#define portNVIC_LP_TIMER_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<0) /* priority of low power timer interrupt */ + +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT +#define IRQn_Type int +#define __NVIC_PRIO_BITS configPRIO_BITS +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; +#else /* M0+ */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; +#endif + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + +/** \brief Set Interrupt Priority + The function sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +static void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); /* set Priority for device specific Interrupts */ +#else /* M0+ */ + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); /* set Priority for device specific Interrupts */ +#endif +} + +/** \brief Enable External Interrupt + The function enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +static void NVIC_EnableIRQ(IRQn_Type IRQn) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +#else /* M0+ */ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +#endif +} +#endif /* configSYSTICK_USE_LOW_POWER_TIMER */ + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR (0x01000000) +#define portINITIAL_EXEC_RETURN (0xfffffffd) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED (0x03) +#define portINITIAL_CONTROL_IF_PRIVILEGED (0x02) + +#if configENABLE_FPU + /* Constants required to manipulate the VFP. */ + #define portFPCCR ((volatile unsigned long *)0xe000ef34) /* Floating point context control register. */ + #define portASPEN_AND_LSPEN_BITS (0x3UL<<30UL) +#endif +#endif +/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). + This will be set to 0 prior to the first task being started. */ +/* Each task maintains its own interrupt status in the critical nesting variable. */ +static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; + +#if INCLUDE_vTaskEndScheduler +#include +static jmp_buf xJumpBuf; /* Used to restore the original context when the scheduler is ended. */ +#endif +/*-----------------------------------------------------------*/ +void prvTaskExitError(void) { + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT(uxCriticalNesting == ~0UL); + portDISABLE_INTERRUPTS(); + for(;;) { + /* wait here */ + } +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) /* ARM M4(F)/M7/M33 core */ +__asm uint32_t ulPortSetInterruptMask(void) { + PRESERVE8 + + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) +__asm void vPortClearInterruptMask(uint32_t ulNewMask) { + PRESERVE8 + + msr basepri, r0 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if configENABLE_MPU +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged) { +#else +StackType_t *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { +#endif + /* Simulate the stack frame as it would be created by a context switch interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts, and to ensure alignment. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; +#if configENABLE_MPU + *pxTopOfStack = ((StackType_t)pxCode)&portSTART_ADDRESS_MASK; /* PC */ +#else + *pxTopOfStack = ((StackType_t)pxCode); /* PC */ +#endif + pxTopOfStack--; + *pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialization. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = (portSTACK_TYPE)pvParameters; /* R0 */ + +#if configENABLE_FPU /* has floating point unit */ + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; +#endif +#if configENABLE_MPU + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4 plus privilege level */ + if (xRunPrivileged == pdTRUE) { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } else { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } +#else + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ +#endif + return pxTopOfStack; +} + +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_S08_FSL) || (configCOMPILER==configCOMPILER_S12_FSL) +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma MESSAGE DISABLE C20000 /* dead code detected */ + #pragma NO_RETURN + #pragma CODE_SEG __NEAR_SEG NON_BANKED +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma NO_RETURN +#endif + +static portBASE_TYPE xBankedStartScheduler(void) { + /* Restore the context of the first task. */ + portRESTORE_CONTEXT(); /* Simulate the end of an interrupt to start the scheduler off. */ + /* Should not get here! */ + return pdFALSE; +} + +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma CODE_SEG DEFAULT + #pragma MESSAGE DEFAULT C1404 /* return expected */ + #pragma MESSAGE DEFAULT C20000 /* dead code detected */ +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DEFAULT C1404 /* return expected */ +#endif +#endif +/*-----------------------------------------------------------*/ +#if configUSE_TICKLESS_IDLE == 1 +void FRTOS1_vOnPreSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +void FRTOS1_vOnPostSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +#if (configCOMPILER==configCOMPILER_ARM_GCC) || (configCOMPILER==configCOMPILER_ARM_KEIL) +__attribute__((weak)) +#endif +void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { + unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements; + TickCounter_t tmp; /* because of how we get the current tick counter */ + bool tickISRfired; + uint32_t tickDuration; + +#if configSYSTICK_USE_LOW_POWER_TIMER + /* if we wait for the tick interrupt, do not enter low power again below */ + if (restoreTickInterval!=0) { + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* default example code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + return; + } +#endif + + /* Make sure the tick timer reload value does not overflow the counter. */ + if(xExpectedIdleTime > xMaximumPossibleSuppressedTicks) { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the tick timer momentarily. The time the counter is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else /* using normal timer or SysTick */ + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. This code will execute part way through one + * of the tick periods. + */ + /* -1UL is used because this code will execute part way through one of the tick periods */ +#if COUNTS_UP + ulReloadValue = (UL_TIMER_COUNTS_FOR_ONE_TICK*xExpectedIdleTime); + #if configSYSTICK_USE_LOW_POWER_TIMER + if (ulReloadValue > 0) { /* make sure it does not underflow */ + ulReloadValue -= 1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + } + #endif + if (tmp!=0 && ulReloadValue>=tmp) { /* make sure it does not underflow */ + ulReloadValue -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + ulReloadValue = tmp+(UL_TIMER_COUNTS_FOR_ONE_TICK*(xExpectedIdleTime-1UL)); +#endif + if (ulStoppedTimerCompensation!=0 && ulReloadValue>ulStoppedTimerCompensation) { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. + */ + TICKLESS_DISABLE_INTERRUPTS(); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. + */ + if (eTaskConfirmSleepModeStatus()==eAbortSleep) { + /* Must restore the duration before re-enabling the timers */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK-1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tmp!=0 && tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + tickDuration = tmp; +#endif + SET_TICK_DURATION(tickDuration); + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICKLESS_ENABLE_INTERRUPTS(); + } else { + SET_TICK_DURATION(ulReloadValue); /* Set the new reload value. */ + RESET_TICK_COUNTER_VAL(); /* Reset the counter. */ + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICK_INTERRUPT_FLAG_RESET(); /* reset flag so we know later if it has fired */ + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. + */ + + /* CPU *HAS TO WAIT* in the sequence below for an interrupt. If vOnPreSleepProcessing() is not used, a default implementation is provided */ + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* example/default code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + /* ---------------------------------------------------------------------------- + * Here the CPU *HAS TO BE* low power mode, waiting to wake up by an interrupt + * ----------------------------------------------------------------------------*/ + FRTOS1_vOnPostSleepProcessing(xExpectedIdleTime); /* process post-low power actions */ + /* Stop tick counter. Again, the time the tick counter is stopped for is + * accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ + tickISRfired = (bool)TICK_INTERRUPT_HAS_FIRED(); /* need to check Interrupt flag here, as might be modified below */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + TICKLESS_ENABLE_INTERRUPTS();/* Re-enable interrupts */ + if (tickISRfired) { + /* The tick interrupt has already executed, and the timer + * count reloaded with the modulo/match value. + * Reset the counter register with whatever remains of + * this tick period. + */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; + } + if (tickDuration > 1) { + /*! \todo Need to rethink this one! */ + //tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + vTaskStepTick(1); + } +#else + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)-(ulReloadValue-tmp); +#endif + SET_TICK_DURATION(tickDuration); + /* The tick interrupt handler will already have pended the tick + * processing in the kernel. As the pending tick will be + * processed as soon as this function exits, the tick value + * maintained by the tick is stepped forward by one less than the + * time spent waiting. + */ + ulCompleteTickPeriods = xExpectedIdleTime-1UL; /* -1 because we already added a completed tick from the tick interrupt */ + } else { + /* Something other than the tick interrupt ended the sleep. + * Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part ticks). + */ +#if COUNTS_UP + ulCompletedSysTickIncrements = tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = (((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-1)-ulCompletedSysTickIncrements; + if (tickDuration > 1) { + tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + if (tickDuration > 1) { /* check for underflow */ + tickDuration -= 1; + } + vTaskStepTick(1); + } +#else + ulCompletedSysTickIncrements = (xExpectedIdleTime*UL_TIMER_COUNTS_FOR_ONE_TICK)-tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = ((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-ulCompletedSysTickIncrements; +#endif + SET_TICK_DURATION(tickDuration); + } + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. + */ + RESET_TICK_COUNTER_VAL(); + portENTER_CRITICAL(); + { + ENABLE_TICK_COUNTER(); + if (ulCompleteTickPeriods>0) { + vTaskStepTick(ulCompleteTickPeriods); + } +#if configSYSTICK_USE_LOW_POWER_TIMER + /* The compare register of the LPTMR should not be modified when the + * timer is running, so wait for the next tick interrupt to change it. + */ + if (tickDuration != (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)) { /* minus one because of LPTMR way to trigger interrupts */ + if (tickISRfired) { + /* The pending tick interrupt will be immediately processed after + * exiting this function so we need to delay the change of the tick + * duration until the one after that. + */ + restoreTickInterval = 2; + } else { + /* Notify the tick interrupt that the tick duration needs to be + * changed back to the normal setting. + */ + restoreTickInterval = 1; + } + } else { + /* If the duration is the standard full tick, then there's no reason + * to stop and restart LPTMR in the tick interrupt. + */ + restoreTickInterval = 0; + } +#else + /* The systick has a load register that will automatically be used + * when the counter counts down to zero. + */ + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); +#endif + } + portEXIT_CRITICAL(); + } +} +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ +static void vPortInitTickTimer(void) { +#if configUSE_TICKLESS_IDLE == 1 +{ +#if TICK_NOF_BITS==32 + xMaximumPossibleSuppressedTicks = 0xffffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 32bit timer register */ +#elif TICK_NOF_BITS==24 + xMaximumPossibleSuppressedTicks = 0xffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 24bit timer register */ +#elif TICK_NOF_BITS==16 + xMaximumPossibleSuppressedTicks = 0xffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 16bit timer register */ +#elif TICK_NOF_BITS==8 + xMaximumPossibleSuppressedTicks = 0xffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 8bit timer register */ +#else + error "unknown configuration!" +#endif +#if configSYSTICK_USE_LOW_POWER_TIMER + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ); +#else + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_CLOCK_HZ); +#endif +} +#endif /* configUSE_TICKLESS_IDLE */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* SIM_SCGx: enable clock to LPTMR */ +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); + + /* LPTRM0_CSR: clear TCF (Timer compare Flag) with writing a one to it */ + LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR); + + /* LPTMR_PSR: configure prescaler, bypass and clock source */ + /* PBYP PCS + * ERCLK32 1 10 + * LPO_1kHz 1 01 + * ERCLK 0 00 + * IRCLK 1 00 + */ + LPTMR_PDD_SelectPrescalerSource(LPTMR0_BASE_PTR, LPTMR_PDD_SOURCE_LPO1KHZ); + LPTMR_PDD_EnablePrescalerBypass(LPTMR0_BASE_PTR, LPTMR_PDD_BYPASS_ENABLED); +#elif MCUC1_CONFIG_NXP_SDK_2_0_USED + /*! \todo */ + { + lptmr_config_t config; + + LPTMR_GetDefaultConfig(&config); + LPTMR_Init(LPTMR0_BASE_PTR, &config); + } +#endif + /* set timer interrupt priority in IP[] and enable it in ISER[] */ + NVIC_SetPriority(configLOW_POWER_TIMER_VECTOR_NUMBER, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); + NVIC_EnableIRQ(configLOW_POWER_TIMER_VECTOR_NUMBER); /* enable IRQ in NVIC_ISER[] */ +#else /* use normal SysTick Counter */ + *(portNVIC_SYSPRI3) |= portNVIC_SYSTICK_PRI; /* set priority of SysTick interrupt */ +#endif + /* Configure timer to interrupt at the requested rate. */ + DISABLE_TICK_COUNTER(); /* disable the timer, just in case it is already running */ + SET_TICK_DURATION(TIMER_COUNTS_FOR_ONE_TICK-1UL); /* set tick period */ + RESET_TICK_COUNTER_VAL(); /* reset counter so it starts properly */ + ENABLE_TICK_COUNTER(); /* let it run */ +} +/*-----------------------------------------------------------*/ +static void vPortStartTickTimer(void) { + ENABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +void vPortStopTickTimer(void) { + DISABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +#if configENABLE_FPU /* has floating point unit */ +void vPortEnableVFP(void) { +#if 1 /* configLTO_HELPER: using implementation in C which is portable */ + #define CPACR_REG_MEM ((volatile int*)0xE000ED88) /* location of the CPACR register */ + + *CPACR_REG_MEM |= (0xf<<20); /* Enable CP10 and CP11 coprocessors */ +#else /* below is the original assembly code which fails with -flto because of the constant load */ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +#endif +} +#endif /* M4/M7 */ +/*-----------------------------------------------------------*/ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) && (configASSERT_DEFINED == 1) + /* Constants required to check the validity of an interrupt priority. */ + #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) + #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) + #define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) + #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) + #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) + #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) + #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + #define portPRIGROUP_SHIFT ( 8UL ) + + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +BaseType_t xPortStartScheduler(void) { + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) */ /* ARM M4(F)/M7 core */ + +#if configCPU_FAMILY==configCPU_FAMILY_ARM_M7F + /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 r0p1 port. */ + #define portCPUID (*((volatile uint32_t*)0xE000ed00)) + #define portCORTEX_M7_r0p0_ID (0x410FC270UL) + #define portCORTEX_M7_r0p1_ID (0x410FC271UL) /* this one will require a special port! Writing to the BASEPRIO is not taking effect immediately, even with memory barrier instructions. Workaround: globally disable interrupts before writing to BASEPRIO, then write, then use memory barrier. */ + #define portCORTEX_M7_r0p2_ID (0x410FC272UL) /* is present on the TWR-KV57F220M */ + + configASSERT(portCPUID!=portCORTEX_M7_r0p1_ID); /* this one will require a special port! */ +#endif + + /* Make PendSV, SVCall and SysTick the lowest priority interrupts. SysTick priority will be set in vPortInitTickTimer(). */ +#if 0 /* do NOT set the SVCall priority */ + /* why: execution of an SVC instruction at a priority equal or higher than SVCall can cause a hard fault (at least on Cortex-M4), + see https://community.freescale.com/thread/302511 */ + *(portNVIC_SYSPRI2) |= portNVIC_SVCALL_PRI; /* set priority of SVCall interrupt */ +#endif + *(portNVIC_SYSPRI3) |= portNVIC_PENDSV_PRI; /* set priority of PendSV interrupt */ + uxCriticalNesting = 0; /* Initialize the critical nesting count ready for the first task. */ + vPortInitTickTimer(); /* initialize tick timer */ + vPortStartTickTimer(); /* start tick timer */ +#if configENABLE_FPU /* has floating point unit */ + vPortEnableVFP(); /* Ensure the VFP is enabled - it should be anyway */ + *(portFPCCR) |= portASPEN_AND_LSPEN_BITS; /* Lazy register save always */ +#endif +#if INCLUDE_vTaskEndScheduler + if(setjmp(xJumpBuf) != 0 ) { + /* here we will get in case of a call to vTaskEndScheduler() */ + __asm volatile( + " movs r0, #0 \n" /* Reset CONTROL register and switch back to the MSP stack. */ + " msr CONTROL, r0 \n" + " dsb \n" + " isb \n" + ); + return pdFALSE; + } +#endif + vPortStartFirstTask(); /* Start the first task. */ + /* Should not get here! */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ +void vPortEndScheduler(void) { + vPortStopTickTimer(); + vPortInitializeHeap(); + uxCriticalNesting = 0xaaaaaaaa; + /* Jump back to the processor state prior to starting the + scheduler. This means we are not going to be using a + task stack frame so the task can be deleted. */ +#if INCLUDE_vTaskEndScheduler + longjmp(xJumpBuf, 1); +#else + for(;;){} /* wait here */ +#endif +} +/*-----------------------------------------------------------*/ +void vPortEnterCritical(void) { +/* + * Disable interrupts before incrementing the count of critical section nesting. + * The nesting count is maintained so we know when interrupts should be + * re-enabled. Once interrupts are disabled the nesting count can be accessed + * directly. Each task maintains its own nesting count. + */ + portDISABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + uxCriticalNesting++; +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ + #define portVECTACTIVE_MASK (0xFFUL) + + configASSERT(((*portNVIC_INT_CTRL) & portVECTACTIVE_MASK)==0); + } +#endif + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +void vPortExitCritical(void) { + /* Interrupts are disabled so we can access the nesting count directly. If the + * nesting is found to be 0 (no nesting) then we are leaving the critical + * section and interrupts can be re-enabled. + */ + uxCriticalNesting--; + if (uxCriticalNesting == 0) { + portENABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ +void vPortYieldFromISR(void) { + /* Set a PendSV to request a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT; + /* Barriers are normally not required but do ensure the code is completely + within the specified behavior for the architecture. */ + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +/* return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time */ + uint32_t uxGetTickCounterValue(void) { + long val; + + GET_TICK_CURRENT_VAL(&val); + return val; +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + /* this is how we get here: + RTOSTICKLDD1_Interrupt: + push {r4, lr} + ... RTOSTICKLDD1_OnCounterRestart + bl RTOSTICKLDD1_OnCounterRestart -> push {r4,lr} + pop {r4, lr} mov r4,r0 + bl vPortTickHandler + pop {r4,pc} + */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + portDISABLE_INTERRUPTS(); /* disable interrupts */ +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + taskYIELD(); + } + portENABLE_INTERRUPTS(); /* enable interrupts again */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + ACKNOWLEDGE_TICK_ISR(); +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); /* disable interrupts */ + traceISR_ENTER(); +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + traceISR_EXIT_TO_SCHEDULER(); + taskYIELD(); + } else { + traceISR_EXIT(); + } + portENABLE_INTERRUPTS(); /* re-enable interrupts */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_DSC_FSL) +void vPortStartFirstTask(void) { + /* Restore the context of the first task to run. */ + portRESTORE_CONTEXT(); + /* Simulate the end of the yield function. */ + __asm(rts); +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +__asm void vPortStartFirstTask(void) { +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* Use the NVIC offset register to locate the stack. */ +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 +#endif + /* Globally enable interrupts. */ + cpsie i + /* Call SVC to start the first task. */ + svc 0 + nop + nop + nop +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + extern pxCurrentTCB; + + PRESERVE8 + + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + + ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */ + ldr r1, [r3] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + movs r0, #2 /* Switch to the psp stack. */ + msr CONTROL, r0 + isb + pop {r0-r5} /* Pop the registers that are saved automatically. */ + mov lr, r5 /* lr is now in r5. */ + pop {r3} /* The return address is now in r3. */ + pop {r2} /* Pop and discard the XPSR. */ + cpsie i /* The first task has its context and interrupts can be enabled. */ + bx r3 /* Finally, jump to the user defined task code. */ + + ALIGN +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +/* Need the 'noinline', as latest gcc with -O3 tries to inline it, and gives error message: "Error: symbol `pxCurrentTCBConst2' is already defined" */ +__attribute__((noinline)) +void vPortStartFirstTask(void) { +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* only needed for openOCD or Segger FreeRTOS thread awareness. It needs the symbol uxTopUsedPriority present after linking */ + { + extern volatile const int uxTopUsedPriority; + __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd; + dummy_value_for_openocd = uxTopUsedPriority; + } +#endif +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) + /* reference FreeRTOSDebugConfig, otherwise it might get removed by the linker or optimizations */ + { + extern const uint8_t FreeRTOSDebugConfig[]; + if (FreeRTOSDebugConfig[0]==0) { /* just use it, so the linker cannot remove FreeRTOSDebugConfig[] */ + for(;;); /* FreeRTOSDebugConfig[0] should always be non-zero, so this should never happen! */ + } + } +#endif +#if configHEAP_SCHEME_IDENTIFICATION + extern const uint8_t freeRTOSMemoryScheme; /* constant for NXP Kernel Awareness to indicate heap scheme */ + if (freeRTOSMemoryScheme>100) { /* reference/use variable so it does not get optimized by the linker */ + for(;;); + } +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler +#if configLTO_HELPER /* with -flto, we cannot load the constant directly, otherwise we get "Error: offset out of range" with "lto-wrapper failed" */ + " mov r0, #0xE0000000 \n" /* build the constant 0xE000ED08. First load the upper 16 bits */ + " mov r1, #0xED00 \n" /* next load part of the lower 16 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED00 in R0 */ + " mov r1, #0x08 \n" /* next load the lowest 8 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED08 in R0 */ +#else + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ +#endif + " ldr r0, [r0] \n" /* load address of vector table */ + " ldr r0, [r0] \n" /* load first entry of vector table which is the reset stack pointer */ + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ +#endif + " cpsie i \n" /* Globally enable interrupts. */ + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + __asm volatile( + " ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */ + " ldr r3, [r2] \n" + " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " movs r0, #2 \n" /* Switch to the psp stack. */ + " msr CONTROL, r0 \n" + " isb \n" + " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ + " mov lr, r5 \n" /* lr is now in r5. */ + " pop {r3} \n" /* Return address is now in r3. */ + " pop {r2} \n" /* Pop and discard XPSR. */ + " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ + " bx r3 \n" /* Finally, jump to the user defined task code. */ + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB" + ); +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* \todo: r14, check http://sourceforge.net/p/freertos/discussion/382005/thread/a9406af1/?limit=25#3bc7 */ +#else + ldmia r0!, {r4-r11} +#endif + msr psp, r0 + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 +#if configENABLE_FPU +#else + orr r14, r14, #13 +#endif + bx r14 +} +/*-----------------------------------------------------------*/ +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ and Keil */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + /* This function is no longer used, but retained for backward + compatibility. */ +} +#endif +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void SVC_Handler(void) { +#else +__attribute__ ((naked)) void vPortSVCHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +__asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + /* pop the core registers */ +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" +#else + " ldmia r0!, {r4-r11} \n" +#endif + " msr psp, r0 \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" +#if configENABLE_FPU +#else + " orr r14, r14, #13 \n" +#endif + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* This function is no longer used, but retained for backward + compatibility. */ +#endif +} +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] +#if configENABLE_FPU + tst r14, #0x10 /* Is the task using the FPU context? If so, push high vfp registers. */ + it eq + vstmdbeq r0!, {s16-s31} + + stmdb r0!, {r4-r11, r14} /* save remaining core registers */ +#else + stmdb r0!, {r4-r11} /* Save the core registers. */ +#endif + str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ + stmdb sp!, {r3, r14} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. */ + ldr r0, [r1] +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* Pop the core registers */ + tst r14, #0x10 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + it eq + vldmiaeq r0!, {s16-s31} +#else + ldmia r0!, {r4-r11} /* Pop the core registers. */ +#endif + msr psp, r0 + bx r14 + nop +} +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Keil: Cortex M0+ */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] + + subs r0, #32 /* Make space for the remaining low registers. */ + str r0, [r2] /* Save the new top of stack. */ + stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ + mov r4, r8 /* Store the high registers. */ + mov r5, r9 + mov r6, r10 + mov r7, r11 + stmia r0!, {r4-r7} + + push {r3, r14} + cpsid i + bl vTaskSwitchContext + cpsie i + pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ + + ldr r1, [r2] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #16 /* Move to the high registers. */ + ldmia r0!, {r4-r7} /* Pop the high registers. */ + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + + msr psp, r0 /* Remember the new top of stack for the task. */ + + subs r0, #32 /* Go back for the low registers that are not automatically restored. */ + ldmia r0!, {r4-r7} /* Pop low registers. */ + + bx r3 + nop +} +#endif +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if configGDB_HELPER +/* prototypes to avoid compiler warnings */ +__attribute__ ((naked)) void vPortPendSVHandler_native(void); +__attribute__ ((naked)) void PendSV_Handler_jumper(void); + +__attribute__ ((naked)) void vPortPendSVHandler_native(void) { +#elif !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB" + ); +#endif +} + +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* This is only really needed for debugging with openOCD: + * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer + * present in the kernel, so it has to be supplied by other means for + * OpenOCD's threads awareness. + * + * Add this file to your project, and, if you're using --gc-sections, + * ``--undefined=uxTopUsedPriority'' (or + * ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final + * linking) to your LDFLAGS; same with all the other symbols you need. + */ + volatile const int + #ifdef __GNUC__ + __attribute__((used)) + #endif + uxTopUsedPriority = configMAX_PRIORITIES-1; +#endif + +#if configGDB_HELPER /* if GDB debug helper is enabled */ +/* Credits to: + * - Artem Pisarneko for his initial contribution + * - Prasana for the PendSVHandler updates + * - Geoffrey Wossum for the Cortex-M4 contribution + */ + +/* Switch control variable: + * 0 - no hook installed (normal execution), + * 1 - hook installation performed, + * 2 - following hooked switches + */ +int volatile dbgPendSVHookState = 0; +/* Requested target task handle variable */ +void *volatile dbgPendingTaskHandle; + +const int volatile dbgFreeRTOSConfig_suspend_value = INCLUDE_vTaskSuspend; +const int volatile dbgFreeRTOSConfig_delete_value = INCLUDE_vTaskDelete; + +__attribute__ ((naked)) void PendSV_Handler_jumper(void) { + __asm volatile("b vPortPendSVHandler_native \n"); +} + +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configGDB_HELPER + " ldr r1, _dbgPendSVHookState \n" /* Check hook installed */ + " ldr r0, [r1] \n" + " cmp r0, #0 \n" + " beq PendSV_Handler_jumper \n" /* if no hook installed then jump to native handler, else proceed... */ + " cmp r0, #1 \n" /* check whether hook triggered for the first time... */ + " bne dbg_switch_to_pending_task \n" /* if not so, then jump to switching right now, otherwise current task context must be saved first... */ + " mov r0, #2 \n" /* mark hook after triggered for the first time */ + " str r0, [r1] \n" +#endif /* configGDB_HELPER */ + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" +#if configGDB_HELPER + "dbg_switch_to_pending_task: \n" + " ldr r3, _dbgPendingTaskHandle \n" /* --> Load task handle going to switch to <-- */ +#endif /* configGDB_HELPER */ + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" +#if configGDB_HELPER + " bkpt \n" /* <-- here debugger stops and steps out to target task context */ +#endif /* configGDB_HELPER */ + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB \n" +#if configGDB_HELPER + "_dbgPendSVHookState: .word dbgPendSVHookState \n" + "_dbgPendingTaskHandle: .word dbgPendingTaskHandle \n" + ".word dbgFreeRTOSConfig_suspend_value \n" /* force keep these symbols from cutting away by linker garbage collector */ + ".word dbgFreeRTOSConfig_delete_value \n" +#endif + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB" + ); +#endif +} + +#endif /* configGDB_HELPER */ + +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + +#if configCOMPILER==configCOMPILER_ARM_KEIL +__asm uint32_t vPortGetIPSR(void) { + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +#endif + +#if( configASSERT_DEFINED == 1 ) + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + ulCurrentInterrupt = vPortGetIPSR(); + #else + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + #endif + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +#endif /* ARM M4(F) core */ + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/portTicks.h b/Projects/tinyK20_SolderDispenser/Generated_Code/portTicks.h new file mode 100644 index 0000000..f69c990 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/portTicks.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PORTTICKS_H_ +#define PORTTICKS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Interface header file to the Processor Expert Tick counter. + * This file is used to access the interface, especially for performance + * counters (e.g. for Percepio Trace). + * That way the a module can interface this wrapper header file instead + * of one of the standard FreeRTOS header files. + */ +#include "MCUC1.h" /* include SDK and API used */ + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "Cpu.h" /* include CPU module because of dependency to CPU clock rate */ +#endif +#include "FreeRTOSConfig.h" +#include "portmacro.h" + +#if !MCUC1_CONFIG_PEX_SDK_USED + extern uint32_t SystemCoreClock; /* in Kinetis SDK, this contains the system core clock speed */ +#endif + +/*! + * \brief Return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time + * \return Tick counter value. The value is reset at tick interrupt time. + * */ +uint32_t uxGetTickCounterValue(void); + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define FREERTOS_HWTC_DOWN_COUNTER 0 /* LPTM is counting up */ + #define FREERTOS_HWTC_PERIOD ((1000/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ)-1UL) /* counter is incrementing from zero to this value */ +#else + #define FREERTOS_HWTC_DOWN_COUNTER 1 /* SysTick is counting down */ + #define FREERTOS_HWTC_PERIOD ((configCPU_CLOCK_HZ/configTICK_RATE_HZ)-1UL) /* counter is decrementing from this value to zero */ +#endif + +#if configUSE_TICKLESS_IDLE == 1 + extern volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ +#endif + +#define FREERTOS_HWTC_FREQ_HZ configTICK_RATE_HZ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* using Percepio Trace */ +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_PROCESSOR_EXPERT) + /* tick information for Percepio Trace */ + + /* undefine previous values, where dummy anyway: make sure this header file is included last! */ + #undef TRC_HWTC_COUNT_DIRECTION + #undef TRC_HWTC_PERIOD + #undef TRC_HWTC_DIVISOR + #undef TRC_HWTC_COUNT + + #if FREERTOS_HWTC_DOWN_COUNTER + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is decrementing from this value to zero */ + #else + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is incrementing from zero to this value */ + #endif + + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #if configSYSTICK_USE_LOW_POWER_TIMER + #define TRC_HWTC_DIVISOR 1 /* divisor for slow counter tick value */ + #else + #define TRC_HWTC_DIVISOR 2 /* divisor for fast counter tick value */ + #endif + #else + #define TRC_HWTC_DIVISOR 1 + #endif + + #define TRC_HWTC_COUNT (uxGetTickCounterValue()) + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_IRQ_PRIORITY_ORDER 0 /* 0: lower IRQ prios mean higher priority, 1: otherwise */ + #define TRC_HWTC_FREQ_HZ FREERTOS_HWTC_FREQ_HZ +#endif +#endif /* configUSE_PERCEPIO_TRACE_HOOKS */ + +#ifdef __cplusplus +} +#endif + +#endif /* PORTTICKS_H_ */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/portable.h b/Projects/tinyK20_SolderDispenser/Generated_Code/portable.h new file mode 100644 index 0000000..90ae895 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/portable.h @@ -0,0 +1,183 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifndef portHAS_STACK_OVERFLOW_CHECKING + #define portHAS_STACK_OVERFLOW_CHECKING 0 +#endif + +#ifndef portARCH_NAME + #define portARCH_NAME NULL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #endif +#else + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #endif +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; +void vPortInitializeHeap(void) PRIVILEGED_FUNCTION; /* << EST */ + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/portasm.s b/Projects/tinyK20_SolderDispenser/Generated_Code/portasm.s new file mode 100644 index 0000000..255f7c4 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/portasm.s @@ -0,0 +1,28 @@ +/* file is intentionally empty as not needed for this GNU gcc FreeRTOS port */ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/portmacro.h b/Projects/tinyK20_SolderDispenser/Generated_Code/portmacro.h new file mode 100644 index 0000000..b3299c6 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/portmacro.h @@ -0,0 +1,604 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOSConfig.h" +#include "projdefs.h" /* for pdFALSE, pdTRUE */ + +void vPortStopTickTimer(void); +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ +#ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. +#endif /* configENABLE_TRUSTZONE */ + +#if (configCOMPILER==configCOMPILER_S12_FSL) || (configCOMPILER==configCOMPILER_S08_FSL) + /* disabling some warnings as the RTOS sources are not that clean... */ + #pragma MESSAGE DISABLE C5909 /* assignment in condition */ + #pragma MESSAGE DISABLE C2705 /* possible loss of data */ + #pragma MESSAGE DISABLE C5905 /* multiplication with one */ + #pragma MESSAGE DISABLE C5904 /* division by one */ + #pragma MESSAGE DISABLE C5660 /* removed dead code */ + #pragma MESSAGE DISABLE C5917 /* removed dead assignment */ + #pragma MESSAGE DISABLE C4001 /* condition always FALSE */ +#endif +#if configCOMPILER==configCOMPILER_S12_FSL + #pragma MESSAGE DISABLE C12053 /* SP change not in debug information */ + #pragma MESSAGE DISABLE C12056 /* SP debug information incorrect */ +#endif + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portSTACK_TYPE unsigned long +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portSTACK_TYPE unsigned char +#endif +typedef portSTACK_TYPE StackType_t; + +#define portUSE_CUSTOM_BASE_TYPE 0 /* 1: use custom base type */ + +#if portUSE_CUSTOM_BASE_TYPE + #define portBASE_TYPE char /* custom port base type */ + typedef portBASE_TYPE BaseType_t; + typedef unsigned portBASE_TYPE UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBASE_TYPE long + typedef long BaseType_t; + typedef unsigned long UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBASE_TYPE char + typedef signed char BaseType_t; + typedef unsigned char UBaseType_t; +#endif + +#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)0xffffffff + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif /* 32bit architecture */ + +#endif + +#if( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); + extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* PRIVILEGED_FUNCTION */; +#endif /* configENABLE_TRUSTZONE */ + +#if( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; +#endif /* configENABLE_MPU */ + +/** + * @brief MPU specific constants. + */ +#if( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) +#else + #define portPRIVILEGE_BIT ( 0x0UL ) +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU +/*-----------------------------------------------------------*/ +/* MPU specific constants. */ + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU /* check values for LPC55xx! */ +/* Devices Region. */ +#define portDEVICE_REGION_START_ADDRESS ( 0x50000000 ) +#define portDEVICE_REGION_END_ADDRESS ( 0x5FFFFFFF ) + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ +#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ +#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ +#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ +#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ +#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ +#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ +#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) +#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) +#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) +#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) +#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + +#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ +typedef struct MPURegionSettings +{ + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ +} MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ +typedef struct MPU_SETTINGS +{ + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ +} xMPU_SETTINGS; + +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ +#define portSVC_ALLOCATE_SECURE_CONTEXT 0 +#define portSVC_FREE_SECURE_CONTEXT 1 +#define portSVC_START_SCHEDULER 2 +#define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ +/* Hardware specifics. */ +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define portBYTE_ALIGNMENT 8 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBYTE_ALIGNMENT 1 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH 1 /* stack grows from LOW to HIGH */ +#endif + +#define portTICK_PERIOD_MS ((TickType_t)1000/configTICK_RATE_HZ) +/*-----------------------------------------------------------*/ +/* Critical section management. */ +unsigned long ulPortSetIPL(unsigned portLONG); + +/* If set to 1, then this port uses the critical nesting count from the TCB rather than +maintaining a separate value and then saving this value in the task stack. */ +#define portCRITICAL_NESTING_IN_TCB 0 + + +extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR(void); +extern void vPortClearInterruptMaskFromISR(unsigned portBASE_TYPE); + + +#if configCOMPILER==configCOMPILER_DSC_FSL + /* for DSC, there is a possible skew after enable/disable Interrupts. */ + #define portPOST_ENABLE_DISABLE_INTERRUPTS() \ + asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); +#else + #define portPOST_ENABLE_DISABLE_INTERRUPTS() /* nothing special needed */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* Cortex M4/M7/M33 */ + #if (configCOMPILER==configCOMPILER_ARM_KEIL) + __asm uint32_t ulPortSetInterruptMask(void); + __asm void vPortClearInterruptMask(uint32_t ulNewMask); + + #define portSET_INTERRUPT_MASK() ulPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask(0) + #elif (configCOMPILER==configCOMPILER_ARM_GCC) + /* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ + #define portSET_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, %0 \n" \ + " msr basepri, r0 \n" \ + : /* no output operands */ \ + :"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) /* input */\ + :"r0" /* clobber */ \ + ) + /* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. + */ + #define portCLEAR_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, #0 \n" \ + " msr basepri, r0 \n" \ + : /* no output */ \ + : /* no input */ \ + :"r0" /* clobber */ \ + ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) /* IAR */ || (configCOMPILER==configCOMPILER_ARM_FSL) /* legacy FSL ARM Compiler */ + void vPortSetInterruptMask(void); /* prototype, implemented in portasm.s */ + void vPortClearInterruptMask(void); /* prototype, implemented in portasm.s */ + #define portSET_INTERRUPT_MASK() vPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask() + #else + #error "unknown compiler?" + #endif +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex-M0+ */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + #define portSET_INTERRUPT_MASK() __disable_irq() + #define portCLEAR_INTERRUPT_MASK() __enable_irq() + #else /* IAR, CW ARM or GNU ARM gcc */ + #define portSET_INTERRUPT_MASK() __asm volatile("cpsid i") + #define portCLEAR_INTERRUPT_MASK() __asm volatile("cpsie i") + #endif +#endif + +/* Critical section management. */ +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#if configCOMPILER==configCOMPILER_ARM_KEIL + #define portDISABLE_ALL_INTERRUPTS() __disable_irq() + #define portENABLE_ALL_INTERRUPTS() __enable_irq() +#else /* IAR, CW ARM or GNU ARM gcc */ + #define portDISABLE_ALL_INTERRUPTS() __asm volatile("cpsid i") + #define portENABLE_ALL_INTERRUPTS() __asm volatile("cpsie i") +#endif + +/* There are an uneven number of items on the initial stack, so +portALIGNMENT_ASSERT_pxCurrentTCB() will trigger false positive asserts. */ +#define portALIGNMENT_ASSERT_pxCurrentTCB (void) + +#if( configENABLE_TRUSTZONE == 1 ) + /** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + + /** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) +#else + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) + #define portCLEAN_UP_TCB( pxTCB ) +#endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + + /** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() +#else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + + +/*-----------------------------------------------------------*/ +/* Scheduler utilities. */ + +extern void vPortYieldFromISR(void); +#define portYIELD() vPortYieldFromISR() +#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } } +#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimizations. */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) + #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + /* Generic helper function. */ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + __attribute__((always_inline)) static inline unsigned char ucPortCountLeadingZeros(unsigned long ulBitmap) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + #endif + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_KEIL) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( ( uint32_t ) __CLZ( ( uxReadyPriorities ) ) ) ) + #endif + + #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7 */ +/*-----------------------------------------------------------*/ + +#ifdef configASSERT +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) /* ARM M4/M7(F) core */ + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif +#endif + +/*-----------------------------------------------------------*/ +/* 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 +/*-----------------------------------------------------------*/ +/* 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) +/*-----------------------------------------------------------*/ +void vPortStartFirstTask(void); + /* starts the first task, called from xPortStartScheduler() */ + +void vPortYieldHandler(void); + /* handler for the SWI interrupt */ + +#if configENABLE_FPU /* has floating point unit */ + void vPortEnableVFP(void); + /* enables floating point support in the CPU */ +#endif + +/* Prototypes for interrupt service handlers */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ + void SVC_Handler(void); /* SVC interrupt handler */ + void PendSV_Handler(void); /* PendSV interrupt handler */ + void SysTick_Handler(void); /* Systick interrupt handler */ +#else + void vPortSVCHandler(void); /* SVC interrupt handler */ + void vPortPendSVHandler(void); /* PendSV interrupt handler */ + void vPortTickHandler(void); /* Systick interrupt handler */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC) + #define portINLINE __inline + + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) + #endif + + #if configENABLE_MPU + /* Set the privilege level to user mode if xRunningPrivileged is false. */ + portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) + { + if( xRunningPrivileged != pdTRUE ) + { + __asm volatile ( " mrs r0, control \n" \ + " orr r0, #1 \n" \ + " msr control, r0 \n" \ + :::"r0" ); + } + } + #endif + + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) + { + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortRaiseBASEPRI( void ) + { + uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) + { + uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; + } + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) + { + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); + } + /*-----------------------------------------------------------*/ +#endif + +#if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + BaseType_t configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME(void); /* return pdTRUE if RTOS can enter tickless idle mode, pdFALSE otherwise */ +#endif + +void prvTaskExitError(void); + /* handler to catch task exit errors */ + +#if !configGENERATE_RUN_TIME_STATS_USE_TICKS + extern void FRTOS1_AppConfigureTimerForRuntimeStats(void); + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/projdefs.h b/Projects/tinyK20_SolderDispenser/Generated_Code/projdefs.h new file mode 100644 index 0000000..762e5c7 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/projdefs.h @@ -0,0 +1,125 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/queue.c b/Projects/tinyK20_SolderDispenser/Generated_Code/queue.c new file mode 100644 index 0000000..3caadde --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/queue.c @@ -0,0 +1,2947 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( int8_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +Queue_t structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +structure instead holds a pointer to the mutex holder (if any). Map alternative +names to the pcHead and structure member to ensure the readability of the code +is maintained. The QueuePointers_t and SemaphoreData_t types are used to form +a union as their usage is mutually exclusive dependent on what the queue is +being used for. */ +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +typedef struct QueuePointers +{ + int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ +} QueuePointers_t; + +typedef struct SemaphoreData +{ + TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ +} SemaphoreData_t; + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. See the following link for the + * rationale: https://www.freertos.org/Embedded-RTOS-Queues.html + */ +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ + int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union + { + QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ + } u; + + List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ + UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t +name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char *pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + + /* The old xQueueRegistryItem name is maintained above then typedefed to the + new xQueueRegistryItem name below to enable the use of older kernel aware + debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + + /* The queue registry is simply an array of QueueRegistryItem_t structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + +#if( configUSE_MUTEXES == 1 ) + /* + * If a task waiting for a mutex causes the mutex holder to inherit a + * priority, but the waiting task times out, then the holder should + * disinherit the priority - but only down to the highest priority of any + * other tasks that are waiting for the same mutex. This function returns + * that priority. + */ + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; +#endif +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->cRxLock = queueUNLOCKED; + pxQueue->cTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + /* The StaticQueue_t structure and the queue storage area must be + supplied. */ + configASSERT( pxStaticQueue != NULL ); + + /* A queue storage area should be provided if the item size is not 0, and + should not be provided if the item size is 0. */ + configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); + configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticQueue_t or StaticSemaphore_t equals the size of + the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + configASSERT( xSize == sizeof( Queue_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + The address of a statically allocated storage area was also passed in + but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewQueue != NULL ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + note this queue was allocated statically in case the queue is + later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + size_t xQueueSizeInBytes; + uint8_t *pucQueueStorage; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* There is not going to be a queue storage area. */ + xQueueSizeInBytes = ( size_t ) 0; + } + else + { + /* Allocate enough space to hold the maximum number of items that + can be in the queue at any time. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + + /* Allocate the queue and storage area. Justification for MISRA + deviation as follows: pvPortMalloc() always ensures returned memory + blocks are aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the Queue_t structure - which in this case + is an int8_t *. Therefore, whenever the stack alignment requirements + are greater than or equal to the pointer to char requirements the cast + is safe. In other cases alignment requirements are not strict (one or + two bytes). */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + storage area. */ + pucQueueStorage = ( uint8_t * ) pxNewQueue; + pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + note this task was created dynamically in case it is later + deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) +{ + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* No RAM was allocated for the queue storage area, but PC head cannot + be set to NULL because NULL is used as a key to say the queue is used as + a mutex. Therefore just set pcHead to point to the queue as a benign + value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; + } + else + { + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; + } + + /* Initialise the queue members as described where the queue type is + defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static void prvInitialiseMutex( Queue_t *pxNewQueue ) + { + if( pxNewQueue != NULL ) + { + /* The queue create function will set all the queue structure members + correctly for a generic queue, but this function is creating a + mutex. Overwrite those members that need to be set differently - + in particular the information required for priority inheritance. */ + pxNewQueue->u.xSemaphore.xMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* In case this is a recursive mutex. */ + pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0; + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + xNewQueue = xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + xNewQueue = xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + + configASSERT( xSemaphore ); + + /* Mutexes cannot be used in interrupt service routines, so the mutex + holder should not change in an ISR, and therefore a critical section is + not required here. */ + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then xMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--; + + /* Has the recursive call count unwound to 0? */ + if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait ); + + /* pdPASS will only be returned if the mutex was successfully + obtained. The calling task may have entered the Blocked state + before reaching here. */ + if( xReturn != pdFAIL ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) +{ +BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be the + highest priority task wanting to access the queue. If the head item + in the queue is to be overwritten then it does not matter if the + queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; + + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) + { + /* Do not notify the queue set as an existing item + was overwritten in the queue so the number of items + in the queue has not changed. */ + mtCOVERAGE_TEST_MARKER(); + } + else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes + and the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + in the queue. Also don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a + semaphore or mutex. That means prvCopyDataToQueue() cannot result + in a task disinheriting a priority and prvCopyDataToQueue() can be + called here even though the disinherit function does not check if + the scheduler is suspended before accessing the ready lists. */ + ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + /* Similar to xQueueGenericSendFromISR() but used with semaphores where the + item size is 0. Don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + + configASSERT( pxQueue ); + + /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() + if the item size is not 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Normally a mutex would not be given from an interrupt, especially if + there is a mutex holder, as priority inheritance makes no sense for an + interrupts, only tasks. */ + configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* When the queue is used to implement a semaphore no data is ever + moved through the queue but it is still valid to see if the queue 'has + space'. */ + if( uxMessagesWaiting < pxQueue->uxLength ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* A task can only have an inherited priority if it is a mutex + holder - and if there is a mutex holder then the mutex cannot be + given from an ISR. As this is the ISR version of the function it + can be assumed there is no mutex holder and no need to determine if + priority disinheritance is needed. Simply increase the count of + messages (semaphores) available. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The semaphore is a member of a queue set, and + posting to the queue set caused a higher priority + task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data available, remove one item. */ + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_RECEIVE( pxQueue ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* There is now space in the queue, were any tasks waiting to + post to the queue? If so, unblock the highest priority waiting + task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* The timeout has not expired. If the queue is still empty place + the task on the list of tasks waiting to receive from the queue. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The queue contains data again. Loop back to try and read the + data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. If there is no data in the queue exit, otherwise loop + back and attempt to read the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + +#if( configUSE_MUTEXES == 1 ) + BaseType_t xInheritanceOccurred = pdFALSE; +#endif + + /* Check the queue pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* Check this really is a semaphore, in which case the item size will be + 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Semaphores are queues with an item size of 0, and where the + number of messages in the queue is the semaphore's count value. */ + const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxSemaphoreCount > ( UBaseType_t ) 0 ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Semaphores are queues with a data size of zero and where the + messages waiting is the semaphore's count. Reduce the count. */ + pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1; + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + /* Check to see if other tasks are blocked waiting to give the + semaphore, and if so, unblock the highest priority such task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* For inheritance to have occurred there must have been an + initial timeout, and an adjusted timeout cannot become 0, as + if it were 0 the function would have exited. */ + #if( configUSE_MUTEXES == 1 ) + { + configASSERT( xInheritanceOccurred == pdFALSE ); + } + #endif /* configUSE_MUTEXES */ + + /* The semaphore count was 0 and no block time is specified + (or the block time has expired) so exit now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The semaphore count was 0 and a block time was specified + so configure the timeout structure ready to block. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can give to and take from the semaphore + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* A block time is specified and not expired. If the semaphore + count is 0 then enter the Blocked state to wait for a semaphore to + become available. As semaphores are implemented with queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There was no timeout and the semaphore count was not 0, so + attempt to take the semaphore again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* If the semaphore count is 0 exit now as the timeout has + expired. Otherwise return to attempt to take the semaphore that is + known to be available. As semaphores are implemented by queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + #if ( configUSE_MUTEXES == 1 ) + { + /* xInheritanceOccurred could only have be set if + pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to + test the mutex type again to check it is actually a mutex. */ + if( xInheritanceOccurred != pdFALSE ) + { + taskENTER_CRITICAL(); + { + UBaseType_t uxHighestWaitingPriority; + + /* This task blocking on the mutex caused another + task to inherit this task's priority. Now this task + has timed out the priority should be disinherited + again, but only as low as the next highest priority + task that is waiting for the same mutex. */ + uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); + vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); + } + taskEXIT_CRITICAL(); + } + } + #endif /* configUSE_MUTEXES */ + + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position so it can be reset after the data + is read from the queue as this function is only peeking the + data, not removing it. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read pointer. */ + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure ready to enter the blocked + state. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* Timeout has not expired yet, check to see if there is data in the + queue now, and if not enter the Blocked state to wait for data. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There is data in the queue now, so don't enter the blocked + state, instead return to try and obtain the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. If there is still no data in the queue + exit, otherwise go back and try to read the data again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Cannot block in an ISR, so check there is data available. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + const int8_t cRxLock = pxQueue->cRxLock; + + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( cRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + traceQUEUE_DELETE( pxQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + again. */ + vPortFree( pxQueue ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else + { + /* The queue must have been statically allocated, so is not going to be + deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) + { + UBaseType_t uxHighestPriorityOfWaitingTasks; + + /* If a task waiting for a mutex causes the mutex holder to inherit a + priority, but the waiting task times out, then the holder should + disinherit the priority - but only down to the highest priority of any + other tasks that are waiting for the same mutex. For this purpose, + return the priority of the highest priority task that is waiting for the + mutex. */ + if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0U ) + { + uxHighestPriorityOfWaitingTasks = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) ); + } + else + { + uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY; + } + + return uxHighestPriorityOfWaitingTasks; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) +{ +BaseType_t xReturn = pdFALSE; +UBaseType_t uxMessagesWaiting; + + /* This function is called from a critical section. */ + + uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder ); + pxQueue->u.xSemaphore.xMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */ + pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --uxMessagesWaiting; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + int8_t cTxLock = pxQueue->cTxLock; + + /* See if data was added to the queue while it was locked. */ + while( cTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get + added to the pending ready list as the scheduler is still + suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that + a context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --cTxLock; + } + + pxQueue->cTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + int8_t cRxLock = pxQueue->cRxLock; + + while( cRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --cRxLock; + } + else + { + break; + } + } + + pxQueue->cRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char *pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + const char *pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + /* Note there is nothing here to protect against another task adding or + removing entries from the registry while it is being searched. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + pcReturn = xQueueRegistry[ ux ].pcQueueName; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return pcReturn; + } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + + /* Set the handle to NULL to ensure the same queue handle cannot + appear in the registry twice if it is added, removed, then + added again. */ + xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + Queue_t * const pxQueue = xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + const int8_t cTxLock = pxQueueSetContainer->cTxLock; + + traceQUEUE_SEND( pxQueueSetContainer ); + + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + + if( cTxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxQueueSetContainer->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + +/*-----------------------------------------------------------*/ +void vQueueEndScheduler(void) { /* << EST */ +#if configQUEUE_REGISTRY_SIZE>0 + memset(xQueueRegistry, 0, sizeof(xQueueRegistry)); +#endif /* configQUEUE_REGISTRY_SIZE */ +} + + + + + + + + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/queue.h b/Projects/tinyK20_SolderDispenser/Generated_Code/queue.h new file mode 100644 index 0000000..dc48ef7 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/queue.h @@ -0,0 +1,1657 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void * const pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +void vQueueEndScheduler(void); /* << EST */ + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/readme_gdbBacktraceDebug.txt b/Projects/tinyK20_SolderDispenser/Generated_Code/readme_gdbBacktraceDebug.txt new file mode 100644 index 0000000..b4e0d4f --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/readme_gdbBacktraceDebug.txt @@ -0,0 +1,31 @@ +readme.txt +---------- +Tasks backtrace switcher/viewer snippet is from the following FreeRTOS Interactive site: +http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + +It generates the following files: +- readme_gdbBacktraceDebug.txt (this file) +- .gdbinit-FreeRTOS-helpers (GDB script file) + +Usage: +- execute GDB script (either manually or in the launch configuration): + source .//Generated_Code//.gdbinit-FreeRTOS-helpers +- execute + freertos_show_threads + to show threads with handlers +- use + freertos_switch_to_task + to show task stack +- use + freertos_restore_running_context + to restore the context before running + +Credits to: +- Artem Pisarneko for his initial contribution +- Prasana for the PendSVHandler updates +- Geoffrey Wossum for the Cortex-M4 contribution + +Link to article: +http://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/semphr.h b/Projects/tinyK20_SolderDispenser/Generated_Code/semphr.h new file mode 100644 index 0000000..c901d9e --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/semphr.h @@ -0,0 +1,1141 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, but instead buried in a more complex
+            // call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = vSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + +/** + * semphr.h + *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/stack_macros.h b/Projects/tinyK20_SolderDispenser/Generated_Code/stack_macros.h new file mode 100644 index 0000000..d6e4730 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/stack_macros.h @@ -0,0 +1,130 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );/* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.c b/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.c new file mode 100644 index 0000000..d913af3 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.c @@ -0,0 +1,1271 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#if 1 /* << EST: handle HIWARE compiler and C++ mode, where UINT32_MAX does not exist */ +#ifndef __HIWARE__ /* C89 compiler does not know stdint.h */ + #include +#endif +#ifndef UINT32_MAX + #define UINT32_MAX 0xffffffff +#endif +#endif /* << EST */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +#if( configUSE_TASK_NOTIFICATIONS != 1 ) + #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c +#endif + +/* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* If the user has not provided application specific Rx notification macros, +or #defined the notification macros away, them provide default implementations +that uses task notifications. */ +/*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */ +#ifndef sbRECEIVE_COMPLETED + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbRECEIVE_COMPLETED */ + +#ifndef sbRECEIVE_COMPLETED_FROM_ISR + #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbRECEIVE_COMPLETED_FROM_ISR */ + +/* If the user has not provided an application specific Tx notification macro, +or #defined the notification macro away, them provide a default implementation +that uses task notifications. */ +#ifndef sbSEND_COMPLETED + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbSEND_COMPLETED */ + +#ifndef sbSEND_COMPLETE_FROM_ISR + #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbSEND_COMPLETE_FROM_ISR */ +/*lint -restore (9026) */ + +/* The number of bytes used to hold the length of a message in the buffer. */ +#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + +/* Bits stored in the ucFlags field of the stream buffer. */ +#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ +#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + +/*-----------------------------------------------------------*/ + +/* Structure that hold state information on the buffer. */ +typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ +{ + volatile size_t xTail; /* Index to the next item to read within the buffer. */ + volatile size_t xHead; /* Index to the next item to write within the buffer. */ + size_t xLength; /* The length of the buffer pointed to by pucBuffer. */ + size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */ + volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */ + volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */ + uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */ + uint8_t ucFlags; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ + #endif +} StreamBuffer_t; + +/* + * The number of bytes available to be read from the buffer. + */ +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION; + +/* + * Add xCount bytes from pucData into the pxStreamBuffer message buffer. + * Returns the number of bytes written, which will either equal xCount in the + * success case, or 0 if there was not enough space in the buffer (in which case + * no data is written into the buffer). + */ +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then reads an entire + * message out of the buffer. If the stream buffer is being used as a stream + * buffer then read as many bytes as possible from the buffer. + * prvReadBytesFromBuffer() is called to actually extract the bytes from the + * buffer's data storage area. + */ +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then writes an entire + * message to the buffer. If the stream buffer is being used as a stream + * buffer then write as many bytes as possible to the buffer. + * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's + * data storage area. + */ +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) PRIVILEGED_FUNCTION; + +/* + * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them + * to pucData. + */ +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, + uint8_t *pucData, + size_t xMaxCount, + size_t xBytesAvailable ) PRIVILEGED_FUNCTION; + +/* + * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to + * initialise the members of the newly created stream buffer structure. + */ +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) + { + uint8_t *pucAllocatedMemory; + uint8_t ucFlags; + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + if( xIsMessageBuffer == pdTRUE ) + { + /* Is a message buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* Not a message buffer and not statically allocated. */ + ucFlags = 0; + configASSERT( xBufferSizeBytes > 0 ); + } + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + /* A stream buffer requires a StreamBuffer_t structure and a buffer. + Both are allocated in a single call to pvPortMalloc(). The + StreamBuffer_t structure is placed at the start of the allocated memory + and the buffer follows immediately after. The requested size is + incremented so the free space is returned as the user would expect - + this is a quirk of the implementation that means otherwise the free + space would be reported as one byte smaller than would be logically + expected. */ + xBufferSizeBytes++; + pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ + + if( pucAllocatedMemory != NULL ) + { + prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */ + pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */ + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer ); + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + } + + return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */ + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) + { + StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */ + StreamBufferHandle_t xReturn; + uint8_t ucFlags; + + configASSERT( pucStreamBufferStorageArea ); + configASSERT( pxStaticStreamBuffer ); + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + if( xIsMessageBuffer != pdFALSE ) + { + /* Statically allocated message buffer. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + } + else + { + /* Statically allocated stream buffer. */ + ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED; + } + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticStreamBuffer_t equals the size of the real + message buffer structure. */ + volatile size_t xSize = sizeof( StaticStreamBuffer_t ); + configASSERT( xSize == sizeof( StreamBuffer_t ) ); + } /*lint !e529 xSize is referenced is configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pucStreamBufferStorageArea, + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + /* Remember this was statically allocated in case it is ever deleted + again. */ + pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; + + traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); + + xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */ + } + else + { + xReturn = NULL; + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + } + + return xReturn; + } + +#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + traceSTREAM_BUFFER_DELETE( xStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both the structure and the buffer were allocated using a single call + to pvPortMalloc(), hence only one call to vPortFree() is required. */ + vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */ + } + #else + { + /* Should not be possible to get here, ucFlags must be corrupt. + Force an assert. */ + configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 ); + } + #endif + } + else + { + /* The structure and buffer were not allocated dynamically and cannot be + freed - just scrub the structure so future use will assert. */ + ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn = pdFAIL; + +#if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; +#endif + + configASSERT( pxStreamBuffer ); + + #if( configUSE_TRACE_FACILITY == 1 ) + { + /* Store the stream buffer number so it can be restored after the + reset. */ + uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; + } + #endif + + /* Can only reset a message buffer if there are no tasks blocked on it. */ + taskENTER_CRITICAL(); + { + if( pxStreamBuffer->xTaskWaitingToReceive == NULL ) + { + if( pxStreamBuffer->xTaskWaitingToSend == NULL ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags ); + xReturn = pdPASS; + + #if( configUSE_TRACE_FACILITY == 1 ) + { + pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + #endif + + traceSTREAM_BUFFER_RESET( xStreamBuffer ); + } + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; + + configASSERT( pxStreamBuffer ); + + /* It is not valid for the trigger level to be 0. */ + if( xTriggerLevel == ( size_t ) 0 ) + { + xTriggerLevel = ( size_t ) 1; + } + + /* The trigger level is the number of bytes that must be in the stream + buffer before a task that is waiting for data is unblocked. */ + if( xTriggerLevel <= pxStreamBuffer->xLength ) + { + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel; + xReturn = pdPASS; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xSpace; + + configASSERT( pxStreamBuffer ); + + xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail; + xSpace -= pxStreamBuffer->xHead; + xSpace -= ( size_t ) 1; + + if( xSpace >= pxStreamBuffer->xLength ) + { + xSpace -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xSpace; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn; + + configASSERT( pxStreamBuffer ); + + xReturn = prvBytesInBuffer( pxStreamBuffer ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace = 0; +size_t xRequiredSpace = xDataLengthBytes; +TimeOut_t xTimeOut; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + + /* Overflow? */ + configASSERT( xRequiredSpace > xDataLengthBytes ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + vTaskSetTimeOutState( &xTimeOut ); + + do + { + /* Wait until the required number of bytes are free in the message + buffer. */ + taskENTER_CRITICAL(); + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + + if( xSpace < xRequiredSpace ) + { + /* Clear notification state as going to wait for space. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one writer. */ + configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); + pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle(); + } + else + { + taskEXIT_CRITICAL(); + break; + } + } + taskEXIT_CRITICAL(); + + traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToSend = NULL; + + } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xSpace == ( size_t ) 0 ) + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ); + + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace; +size_t xRequiredSpace = xDataLengthBytes; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) +{ + BaseType_t xShouldWrite; + size_t xReturn; + + if( xSpace == ( size_t ) 0 ) + { + /* Doesn't matter if this is a stream buffer or a message buffer, there + is no space to write. */ + xShouldWrite = pdFALSE; + } + else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 ) + { + /* This is a stream buffer, as opposed to a message buffer, so writing a + stream of bytes rather than discrete messages. Write as many bytes as + possible. */ + xShouldWrite = pdTRUE; + xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); + } + else if( xSpace >= xRequiredSpace ) + { + /* This is a message buffer, as opposed to a stream buffer, and there + is enough space to write both the message length and the message itself + into the buffer. Start by writing the length of the data, the data + itself will be written later in this function. */ + xShouldWrite = pdTRUE; + ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* There is space available, but not enough space. */ + xShouldWrite = pdFALSE; + } + + if( xShouldWrite != pdFALSE ) + { + /* Writes the data itself. */ + xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */ + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + /* Checking if there is data and clearing the notification state must be + performed atomically. */ + taskENTER_CRITICAL(); + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* If this function was invoked by a message buffer read then + xBytesToStoreMessageLength holds the number of bytes used to hold + the length of the next discrete message. If this function was + invoked by a stream buffer read then xBytesToStoreMessageLength will + be 0. */ + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Clear notification state as going to wait for data. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one reader. */ + configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); + pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Wait for data to be available. */ + traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToReceive = NULL; + + /* Recheck the data available after blocking. */ + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ); + sbRECEIVE_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ); + mtCOVERAGE_TEST_MARKER(); + } + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xBytesAvailable, xOriginalTail; +configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn; + + configASSERT( pxStreamBuffer ); + + /* Ensure the stream buffer is being used as a message buffer. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH ) + { + /* The number of bytes available is greater than the number of bytes + required to hold the length of the next message, so another message + is available. Return its length without removing the length bytes + from the buffer. A copy of the tail is stored so the buffer can be + returned to its prior state as the message is not actually being + removed from the buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable ); + xReturn = ( size_t ) xTempReturn; + pxStreamBuffer->xTail = xOriginalTail; + } + else + { + /* The minimum amount of bytes in a message buffer is + ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is + less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid + value is 0. */ + configASSERT( xBytesAvailable == 0 ); + xReturn = 0; + } + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ); + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) +{ +size_t xOriginalTail, xReceivedLength, xNextMessageLength; +configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength; + + if( xBytesToStoreMessageLength != ( size_t ) 0 ) + { + /* A discrete message is being received. First receive the length + of the message. A copy of the tail is stored so the buffer can be + returned to its prior state if the length of the message is too + large for the provided buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable ); + xNextMessageLength = ( size_t ) xTempNextMessageLength; + + /* Reduce the number of bytes available by the number of bytes just + read out. */ + xBytesAvailable -= xBytesToStoreMessageLength; + + /* Check there is enough space in the buffer provided by the + user. */ + if( xNextMessageLength > xBufferLengthBytes ) + { + /* The user has provided insufficient space to read the message + so return the buffer to its previous state (so the length of + the message is in the buffer again). */ + pxStreamBuffer->xTail = xOriginalTail; + xNextMessageLength = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* A stream of bytes is being received (as opposed to a discrete + message), so read as many bytes as possible. */ + xNextMessageLength = xBufferLengthBytes; + } + + /* Read the actual data. */ + xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */ + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +size_t xTail; + + configASSERT( pxStreamBuffer ); + + /* True if no bytes are available. */ + xTail = pxStreamBuffer->xTail; + if( pxStreamBuffer->xHead == xTail ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) +{ +BaseType_t xReturn; +size_t xBytesToStoreMessageLength; +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + /* This generic version of the receive function is used by both message + buffers, which store discrete messages, and stream buffers, which store a + continuous stream of bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + /* True if the available space equals zero. */ + if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) +{ +size_t xNextHead, xFirstLength; + + configASSERT( xCount > ( size_t ) 0 ); + + xNextHead = pxStreamBuffer->xHead; + + /* Calculate the number of bytes that can be added in the first write - + which may be less than the total number of bytes that need to be added if + the buffer will wrap back to the beginning. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount ); + + /* Write as many bytes as can be written in the first write. */ + configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the number of bytes written was less than the number that could be + written in the first write... */ + if( xCount > xFirstLength ) + { + /* ...then write the remaining bytes to the start of the buffer. */ + configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xNextHead += xCount; + if( xNextHead >= pxStreamBuffer->xLength ) + { + xNextHead -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxStreamBuffer->xHead = xNextHead; + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable ) +{ +size_t xCount, xFirstLength, xNextTail; + + /* Use the minimum of the wanted bytes and the available bytes. */ + xCount = configMIN( xBytesAvailable, xMaxCount ); + + if( xCount > ( size_t ) 0 ) + { + xNextTail = pxStreamBuffer->xTail; + + /* Calculate the number of bytes that can be read - which may be + less than the number wanted if the data wraps around to the start of + the buffer. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount ); + + /* Obtain the number of bytes it is possible to obtain in the first + read. Asserts check bounds of read and write. */ + configASSERT( xFirstLength <= xMaxCount ); + configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the total number of wanted bytes is greater than the number + that could be read in the first read... */ + if( xCount > xFirstLength ) + { + /*...then read the remaining bytes from the start of the buffer. */ + configASSERT( xCount <= xMaxCount ); + ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Move the tail pointer to effectively remove the data read from + the buffer. */ + xNextTail += xCount; + + if( xNextTail >= pxStreamBuffer->xLength ) + { + xNextTail -= pxStreamBuffer->xLength; + } + + pxStreamBuffer->xTail = xNextTail; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) +{ +/* Returns the distance between xTail and xHead. */ +size_t xCount; + + xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; + xCount -= pxStreamBuffer->xTail; + if ( xCount >= pxStreamBuffer->xLength ) + { + xCount -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) +{ + /* Assert here is deliberately writing to the entire buffer to ensure it can + be written to without generating exceptions, and is setting the buffer to a + known value to assist in development/debugging. */ + #if( configASSERT_DEFINED == 1 ) + { + /* The value written just has to be identifiable when looking at the + memory. Don't use 0xA5 as that is the stack fill value and could + result in confusion as to what is actually being observed. */ + const BaseType_t xWriteValue = 0x55; + configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); + } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ + #endif + + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ + pxStreamBuffer->pucBuffer = pucBuffer; + pxStreamBuffer->xLength = xBufferSizeBytes; + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; + pxStreamBuffer->ucFlags = ucFlags; +} + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) + { + return xStreamBuffer->uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) + { + xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) + { + return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ); + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.h b/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.h new file mode 100644 index 0000000..7ed8612 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/stream_buffer.h @@ -0,0 +1,856 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t * StreamBufferHandle_t; + + +/** + * message_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
+
+ * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
+
+    // Create a stream buffer that can hold 100 bytes.  The memory used to hold
+    // both the stream buffer structure and the data in the stream buffer is
+    // allocated dynamically.
+    xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
+
+    if( xStreamBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // stream buffer.
+    }
+    else
+    {
+        // The stream buffer was created successfully and can now be used.
+    }
+}
+
+ * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) + +/** + * stream_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
+                                                size_t xTriggerLevelBytes,
+                                                uint8_t *pucStreamBufferStorageArea,
+                                                StaticStreamBuffer_t *pxStaticStreamBuffer );
+
+ * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the streams.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the streams within the stream
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the stream buffer structure.
+StaticStreamBuffer_t xStreamBufferStruct;
+
+void MyFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xTriggerLevel = 1;
+
+    xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
+                                               xTriggerLevel,
+                                               ucBufferStorage,
+                                               &xStreamBufferStruct );
+
+    // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
+    // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
+    // reference the created stream buffer in other stream buffer API calls.
+
+    // Other code that uses the stream buffer can go here.
+}
+
+
+ * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+                          const void *pvTxData,
+                          size_t xDataLengthBytes,
+                          TickType_t xTicksToWait );
+
+ * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: +
+void vAFunction( StreamBufferHandle_t xStreamBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the stream buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the stream buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xStreamBufferSend() times out before there was enough
+        // space in the buffer for the data to be written, but it did
+        // successfully write xBytesSent bytes.
+    }
+
+    // Send the string to the stream buffer.  Return immediately if there is not
+    // enough space in the buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The entire string could not be added to the stream buffer because
+        // there was not enough free space in the buffer, but xBytesSent bytes
+        // were sent.  Could try again to send the remaining bytes.
+    }
+}
+
+ * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+                                 const void *pvTxData,
+                                 size_t xDataLengthBytes,
+                                 BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBufferHandle_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the stream buffer.
+    xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
+                                           ( void * ) pcStringToSend,
+                                           strlen( pcStringToSend ),
+                                           &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // There was not enough free space in the stream buffer for the entire
+        // string to be written, ut xBytesSent bytes were written.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+                             void *pvRxData,
+                             size_t xBufferLengthBytes,
+                             TickType_t xTicksToWait );
+
+ * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: +
+void vAFunction( StreamBuffer_t xStreamBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
+    // Wait in the Blocked state (so not using any CPU processing time) for a
+    // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
+    // available.
+    xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
+                                           ( void * ) ucRxData,
+                                           sizeof( ucRxData ),
+                                           xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains another xRecievedBytes bytes of data, which can
+        // be processed here....
+    }
+}
+
+ * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+                                    void *pvRxData,
+                                    size_t xBufferLengthBytes,
+                                    BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBuffer_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next stream from the stream buffer.
+    xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // ucRxData contains xReceivedBytes read from the stream buffer.
+        // Process the stream here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
+
+ * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; + +StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#endif + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( STREAM_BUFFER_H ) */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/task.h b/Projects/tinyK20_SolderDispenser/Generated_Code/task.h new file mode 100644 index 0000000..85a5b07 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/task.h @@ -0,0 +1,2452 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V10.2.1" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 2 +#define tskKERNEL_VERSION_BUILD 1 + +/* MPU region parameters passed in ulParameters + * of MemoryRegion_t struct. */ +#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) +#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock* TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + configSTACK_DEPTH_TYPE usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; + #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t * const pxTaskBuffer; + #endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  configSTACK_DEPTH_TYPE usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and a handle to the created task is returned. If either + * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and + * NULL is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+// The StaticTask_t variable is only included in the structure when
+// configSUPPORT_STATIC_ALLOCATION is set to 1.  The PRIVILEGED_DATA macro can
+// be used to force the variable into the RTOS kernel's privileged data area.
+static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+
+	&xTaskBuffer; // Holds the task's data structure.
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
+ * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+    // Obtain the handle of a task from its name.
+    xHandle = xTaskGetHandle( "Task_Name" );
+
+    // Check the handle is not NULL.
+    configASSERT( xHandle );
+
+    // Use the handle to obtain further information about the task.
+    vTaskGetInfo( xHandle,
+                  &xTaskDetails,
+                  pdTRUE, // Include the high water mark in xTaskDetails.
+                  eInvalid ); // Include the task state in xTaskDetails.
+ }
+   
+ * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Do not + * call from an interrupt service routine - call + * xTaskGetApplicationTaskTagFromISR() instead. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Can + * be called from an interrupt service routine. + */ + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + + /* Each task contains an array of pointers that is dimensioned by the + configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + kernel does not use the pointers itself, so the application writer can use + the pointers for any purpose they wish. The following two functions are + used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) // < 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer, size_t bufSize);
//<< EST + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer, size_t bufSize) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** +* task. h +*
TickType_t xTaskGetIdleRunTimeCounter( void );
+* +* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS +* must both be defined as 1 for this function to be available. The application +* must also then provide definitions for +* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() +* to configure a peripheral timer/counter and return the timers current count +* value respectively. The counter should be at least 10 times the frequency of +* the tick count. +* +* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total +* accumulated execution time being stored for each task. The resolution +* of the accumulated time value depends on the frequency of the timer +* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. +* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total +* execution time of each task into a buffer, xTaskGetIdleRunTimeCounter() +* returns the total execution time of just the idle task. +* +* @return The total run time of the idle task. This is the amount of time the +* idle task has actually been executing. The unit of time is dependent on the +* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +* portGET_RUN_TIME_COUNTER_VALUE() macros. +* +* \defgroup xTaskGetIdleRunTimeCounter xTaskGetIdleRunTimeCounter +* \ingroup TaskUtils +*/ +TickType_t xTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object.  Examples of such
+ * objects are queues, semaphores, mutexes and event groups.  Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value.  In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified.  The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task.  If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited.  How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * 
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +#ifdef __GNUC__ /* << EST: 'used' attribute need for LTO (Link Time Optimization) */ + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION __attribute__((used)); +#else + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; +#endif + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critial + * section. + */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + +#if 1 /* << EST */ +/*! + \brief Collects all the task handles present in the system and stores them in to an array of task handles. + \param pxTaskHandleArray Pointer to an array of task handles where the handles will be stored. + \param xNofTaskHandlesInArray Number of task handles in the array. + \return Number of task handles stored in array. + */ +UBaseType_t xGetTaskHandles(TaskHandle_t pxTaskHandleArray[], UBaseType_t xNofTaskHandlesInArray); + +/*! + * \brief Returns stack information about the given task handle. + * \param xTask Task handle + * \param ppxStart Returns the start of the stack area. This is the 'bottom' of the stack, with the stack pointer growing to the 'top'. + * \param ppxEnd Returns the end of the stack area. This is the 'top' of the stack where the stack pointer grows to. + * \param ppxTopOfStack Returns the current stack pointer value. + * \param pucStaticallyAllocated 0, if statically allocated, !=0 if allocated dynamically + */ +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated); + +/*! + * \brief Return a pointer to the task start + * \param xTask Task handle + */ +uint8_t* pxTaskGetStackStart(TaskHandle_t xTask); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/tasks.c b/Projects/tinyK20_SolderDispenser/Generated_Code/tasks.c new file mode 100644 index 0000000..d80c87e --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/tasks.c @@ -0,0 +1,5474 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "stack_macros.h" + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) +#include "UTIL1.h" /* interface to utility because used for safe string routines */ /* << EST */ +#endif + +#if (configCOMPILER == configCOMPILER_ARM_IAR) /* << EST: suppress warnings for IAR */ +#pragma diag_suppress=pa082 /* Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement */ +#endif +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting +functions but without including stdio.h here. */ +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* Values that can be assigned to the ucNotifyState member of the TCB. */ +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* Bits used to recored how a task's stack and TCB were allocated. */ +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + +/* If any of the following are set then task stacks are filled with a known +value so the high water mark can be determined. If none of the following are +set then don't fill the stack so there is no unnecessary dependency on memset. */ +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 +#else + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 +#endif + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskRUNNING_CHAR ( 'X' ) +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/* + * Some kernel aware debuggers require the data the debugger needs access to be + * global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/* The name allocated to the Idle task. This can be overridden by defining +configIDLE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configIDLE_TASK_NAME + #define configIDLE_TASK_NAME "IDLE" +#endif + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + List_t *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +/*-----------------------------------------------------------*/ + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ +/* + * Place the task represented by pxTCB which has been in a ready list before + * into the appropriate ready list for the task. + * It is inserted at the end of the list. + */ +#define prvReAddTaskToReadyList( pxTCB ) \ + traceREADDED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ) + +#endif /* configUSE_SEGGER_SYSTEM_VIEWER_HOOKS */ /* << EST */ + +/* + * Several functions take an TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority +of the task to which it belongs (coded to allow it to be held in reverse +priority order). However, it is occasionally borrowed for other purposes. It +is important its value is not updated due to a task priority change while it is +being used for another purpose. The following bit definition is used to inform +the scheduler that the value should not be changed - in which case it is the +responsibility of whichever module is using the value to ensure it gets set back +to its original value when it is released. */ +#if( configUSE_16_BIT_TICKS == 1 ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#else + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t *pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue; + volatile uint8_t ucNotifyState; + #endif + + /* See the comments in FreeRTOS.h with the definition of + tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif + +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name +below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ +PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. -------------------- +xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but +doing so breaks some kernel aware debuggers and debuggers that rely on removing +the static qualifier. */ +#if configLTO_HELPER + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#else + PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#endif + +#if( INCLUDE_vTaskDelete == 1 ) + +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#else + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#endif + PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#else + PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#endif +#endif + +/* Global POSIX errno. Its value is changed upon context switching to match +the errno of the currently running task. */ +#if ( configUSE_POSIX_ERRNO == 1 ) + int FreeRTOS_errno = 0; +#endif + +/* Other file private variables. --------------------------------*/ +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#endif +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA /*static*/ volatile BaseType_t xSchedulerRunning = pdFALSE; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +#endif +PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +/* Context switches are held pending while the scheduler is suspended. Also, +interrupts must not manipulate the xStateListItem of a TCB, or any of the +lists the xStateListItem can be referenced from, if the scheduler is suspended. +If an interrupt needs to unblock a task while the scheduler is suspended then it +moves the task's event list item into the xPendingReadyList, ready for the +kernel to move the task from the pending ready list into the real ready list +when the scheduler is unsuspended. The pending ready list itself can only be +accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + /* Do not move these variables to function scope as doing so prevents the + code working with debuggers that need to remove the static qualifier. */ + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ +#if 1 /* << EST: prevent optimizations and removal of the following variable with -O1, -O2 or -O3, as used by NXP TAD */ + PRIVILEGED_DATA static + #ifdef __GNUC__ + __attribute__((used)) + #endif + uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#else + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#endif + +#endif + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +/* Callback function prototypes. --------------------------*/ +#if( configCHECK_FOR_STACK_OVERFLOW > 0 ) +#if 1 /* << EST */ + extern void configCHECK_FOR_STACK_OVERFLOW_NAME( TaskHandle_t xTask, char *pcTaskName ); +#else + extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); +#endif +#endif + +#if( configUSE_TICK_HOOK > 0 ) + + extern void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +/* File private functions. --------------------------------*/ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* INCLUDE_vTaskSuspend */ + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Searches pxList for a task with name pcNameToQuery - returning a handle to + * the task if it is found, or NULL if the task is not found. + */ +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ); + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + /* + * Helper function used to pad task names with spaces when printing out + * human readable tables of task information. + */ +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) PRIVILEGED_FUNCTION; +#endif + +#endif +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; + +/* + * freertos_tasks_c_additions_init() should only be called if the user definable + * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro + * called by the function. + */ +#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + + static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION; + +#endif + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) + { + TCB_t *pxNewTCB; + TaskHandle_t xReturn; + + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTask_t equals the size of the real task + structure. */ + volatile size_t xSize = sizeof( StaticTask_t ); + configASSERT( xSize == sizeof( TCB_t ) ); + ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */ + } + #endif /* configASSERT_DEFINED */ + + + if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) + { + /* The memory used for the task's TCB and stack are passed into this + function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer != NULL ); + configASSERT( pxTaskDefinition->pxTaskBuffer != NULL ); + + if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note + this task had a statically allocated stack in case it is + later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t *pxStack; + + /* Allocate space for the stack used by the task being created. */ + pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) +{ +StackType_t *pxTopOfStack; +UBaseType_t x; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ + + /* Calculate the top of stack address. This depends on whether the stack + grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as required + by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + #if( configRECORD_STACK_HIGH_ADDRESS == 1 ) + { + /* Also record the stack's high address, which may assist + debugging. */ + pxNewTCB->pxEndOfStack = pxTopOfStack; + } + #endif /* configRECORD_STACK_HIGH_ADDRESS */ + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + if( pcName != NULL ) + { + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + } + else + { + /* The task has not been given a name, so just ensure there is a NULL + terminator when it is read out. */ + pxNewTCB->pcTaskName[ 0 ] = 0x00; + } + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + pxNewTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxNewTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxNewTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxNewTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; + } + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + { + for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) + { + pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + } + } + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + pxNewTCB->ulNotifiedValue = 0; + pxNewTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + } + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + pxNewTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #else /* portUSING_MPU_WRAPPERS */ + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) +{ + /* Ensure interrupts don't access the task lists while the lists are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Increment the uxTaskNumber also so kernel aware debuggers can + detect that the task lists need re-generating. This is done before + portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will + not return. */ + uxTaskNumber++; + + if( pxTCB == pxCurrentTCB ) + { + /* A task is deleting itself. This cannot complete within the + task itself, as a context switch to another task is required. + Place the task in the termination list. The idle task will + check the termination list and free up any memory allocated by + the scheduler for the TCB and stack of the deleted task. */ + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxDeletedTasksWaitingCleanUp; + + /* The pre-delete hook is primarily for the Windows simulator, + in which Windows specific clean up operations are performed, + after which it is not possible to yield away from this task - + hence xYieldPending is used to latch that a context switch is + required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + } + else + { + --uxCurrentNumberOfTasks; + prvDeleteTCB( pxTCB ); + + /* Reset the next expected unblock time in case it referred to + the task that has just been deleted. */ + prvResetNextTaskUnblockTime(); + } + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if it is the currently running task that has just + been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL( xTimeToWake ); + + /* prvAddCurrentTaskToDelayedList() needs the block time, not + the time to wake, so subtract the current tick count. */ + prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + BaseType_t xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == 0 ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t const * pxStateList, *pxDelayedList, *pxOverflowedDelayedList; + const TCB_t * const pxTCB = xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + pxDelayedList = pxDelayedTaskList; + pxOverflowedDelayedList = pxOverflowDelayedTaskList; + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. Is it genuinely suspended or is it blocked + indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + /* The task does not appear on the event list item of + and of the RTOS objects, but could still be in the + blocked state if it is waiting on its notification + rather than waiting on an object. */ + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + eReturn = eBlocked; + } + else + { + eReturn = eSuspended; + } + } + #else + { + eReturn = eSuspended; + } + #endif + } + else + { + eReturn = eBlocked; + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) + { + /* The task being queried is referenced from the deleted + tasks list, or it is not referenced from any lists at + all. */ + eReturn = eDeleted; + } + #endif + + else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the task + that called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn, uxSavedInterruptState; + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* If null is passed in here then it is the priority of the calling + task that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) + { + TCB_t *pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + nothing more than change its priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before + adding it to it's new ready list. As we are in a critical + section we can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired != pdFALSE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + suspended list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task was blocked to wait for a notification, but is + now suspended, so no notification was received. */ + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + } + #endif + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */ + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = xTask; + + /* Accesses xPendingReadyList so must be called from a critical + section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */ + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* The ready list can be accessed even if the scheduler is + suspended because this is inside a critical section. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* A higher priority task may have just been resumed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + but will leave the lists in the correct state for the + next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Ready lists can be accessed so move the task from the + suspended list to the ready list directly. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + is held in the pending ready list until the scheduler is + unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ +BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxIdleTaskTCBBuffer = NULL; + StackType_t *pxIdleTaskStackBuffer = NULL; + uint32_t ulIdleTaskStackSize; + + /* The Idle task is created using user provided RAM - obtain the + address of the RAM then create the idle task. */ + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, + configIDLE_TASK_NAME, + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + + if( xIdleTaskHandle != NULL ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + #else + { + /* The Idle task is being created using dynamically allocated RAM. */ + xReturn = xTaskCreate( prvIdleTask, + configIDLE_TASK_NAME, + configMINIMAL_STACK_SIZE, + ( void * ) NULL, + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* freertos_tasks_c_additions_init() should only be called if the user + definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is + the only macro called by the function. */ + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + { + freertos_tasks_c_additions_init(); + } + #endif + + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to the task that will run first. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + xNextTaskUnblockTime = portMAX_DELAY; + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS + is set to 0 and the following line fails to build then ensure you do not + have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your + FreeRTOSConfig.h file. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + traceTASK_SWITCHED_IN(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); + } + + /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, + meaning xIdleTaskHandle is not used anywhere else. */ + ( void ) xIdleTaskHandle; +} +/*-----------------------------------------------------------*/ + +#if INCLUDE_vTaskEndScheduler /* << EST */ +#include "queue.h" +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + /* << EST initialize back things for properly ending the scheduler */ + /* set back the scheduler and tasks */ + pxCurrentTCB = NULL; + memset(pxReadyTasksLists, 0, sizeof(pxReadyTasksLists)); + memset(&xDelayedTaskList1, 0, sizeof(xDelayedTaskList1)); + pxDelayedTaskList = NULL; + pxOverflowDelayedTaskList = NULL; + memset(&xPendingReadyList, 0, sizeof(xPendingReadyList)); + + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + uxTopReadyPriority = tskIDLE_PRIORITY; + uxPendedTicks = ( UBaseType_t ) 0U; + xYieldPending = pdFALSE; + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ + xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + + /* reset the queues */ + vQueueEndScheduler(); + /* now do the very low level stuff and reset the heap memory if possible */ + /* << EST end */ + vPortEndScheduler(); +} +#endif /* << EST */ +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + BaseType_t. Please read Richard Barry's reply in the following link to a + post in the FreeRTOS support forum before reporting this as a bug! - + http://goo.gl/wu4acr */ + ++uxSchedulerSuspended; + portMEMORY_BARRIER(); +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + + /* uxHigherPriorityReadyTasks takes care of the case where + configUSE_PREEMPTION is 0, so there may be tasks above the idle priority + task that are in the Ready state, even though the idle task is + running. */ + #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + { + if( uxTopReadyPriority > tskIDLE_PRIORITY ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #else + { + const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; + + /* When port optimised task selection is used the uxTopReadyPriority + variable is used as a bit map. If bits other than the least + significant bit are set then there are tasks that have a priority + above the idle priority that are in the Ready state. This takes + care of the case where the co-operative scheduler is in use. */ + if( uxTopReadyPriority > uxLeastSignificantBit ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #endif + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else if( uxHigherPriorityReadyTasks != pdFALSE ) + { + /* There are tasks in the Ready state that have a priority above the + idle priority. This path can only be reached if + configUSE_PREEMPTION is 0. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ +TCB_t *pxTCB = NULL; +BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If the moved task has a priority higher than the current + task then a yield must be performed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxTCB != NULL ) + { + /* A task was unblocked while the scheduler was suspended, + which may have prevented the next unblock time from being + re-calculated, in which case re-calculate it now. Mainly + important for low power tickless implementations, where + this can prevent an unnecessary exit from low power + state. */ + prvResetNextTaskUnblockTime(); + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does + not slip, and that any delayed tasks are resumed at the correct + time. */ + { + UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */ + + if( uxPendedCounts > ( UBaseType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedCounts; + } while( uxPendedCounts > ( UBaseType_t ) 0U ); + + uxPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xYieldPending != pdFALSE ) + { + #if( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ +TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portTICK_TYPE_ENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portTICK_TYPE_EXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ +TickType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +TCB_t *pxTCB; + + /* If null is passed in here then the name of the calling task is being + queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) + { + TCB_t *pxNextTCB, *pxFirstTCB, *pxReturn = NULL; + UBaseType_t x; + char cNextChar; + BaseType_t xBreakLoop; + + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Check each character in the name looking for a match or + mismatch. */ + xBreakLoop = pdFALSE; + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cNextChar = pxNextTCB->pcTaskName[ x ]; + + if( cNextChar != pcNameToQuery[ x ] ) + { + /* Characters didn't match. */ + xBreakLoop = pdTRUE; + } + else if( cNextChar == ( char ) 0x00 ) + { + /* Both strings terminated, a match must have been + found. */ + pxReturn = pxNextTCB; + xBreakLoop = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xBreakLoop != pdFALSE ) + { + break; + } + } + + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t uxQueue = configMAX_PRIORITIES; + TCB_t* pxTCB; + + /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ + configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); + + vTaskSuspendAll(); + { + /* Search the ready lists. */ + do + { + uxQueue--; + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + + if( pxTCB != NULL ) + { + /* Found the handle. */ + break; + } + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + } + + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the suspended list. */ + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + } + } + #endif + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the deleted list. */ + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + } + } + #endif + } + ( void ) xTaskResumeAll(); + + return pxTCB; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + task in the Blocked state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task in the Suspended state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( const TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) + { + TCB_t *pxTCB = xTask; + BaseType_t xReturn; + + configASSERT( pxTCB ); + + vTaskSuspendAll(); + { + /* A task can only be prematurely removed from the Blocked state if + it is actually in the Blocked state. */ + if( eTaskGetState( xTask ) == eBlocked ) + { + xReturn = pdPASS; + + /* Remove the reference to the task from the blocked list. An + interrupt won't touch the xStateListItem because the + scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove it from + the event list too. Interrupts can touch the event list item, + even though the scheduler is suspended, so a critical section + is used. */ + taskENTER_CRITICAL(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + pxTCB->ucDelayAborted = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Place the unblocked task into the appropriate ready list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only be + performed if the unblocked task has a priority that is + equal to or higher than the currently executing task. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Pend the yield to be performed when the scheduler + is unsuspended. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + xReturn = pdFAIL; + } + } + ( void ) xTaskResumeAll(); + + return xReturn; + } + +#endif /* INCLUDE_xTaskAbortDelay */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskIncrementTick( void ) +{ +TCB_t * pxTCB; +TickType_t xItemValue; +BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; + + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + xTickCount = xConstTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */ + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + the queue in the order of their wake time - meaning once one task + has been found whose block time has not expired there is no need to + look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + to the maximum possible value so it is extremely + unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + break; + } + else + { + /* The delayed list is not empty, get the value of the + item at the head of the delayed list. This is the time + at which the task at the head of the delayed list must + be removed from the Blocked state. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + item value is the time at which the task at the head + of the blocked list must be removed from the Blocked + state - so record the item value in + xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; /*lint !e9011 Code structure here is deedmed easier to understand with multiple breaks. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove + it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + only be performed if the unblocked task has a + priority that is equal to or higher than the + currently executing task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( UBaseType_t ) 0U ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + #endif + } + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + { + TCB_t *xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xTCB->pxTaskTag = pxHookFunction; + } + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = pxTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = pxTCB->pxTaskTag; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + TCB_t *xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#ifdef __GNUC__ /* << EST */ +__attribute__((used)) /* using C++ compiler, vTaskSwitchContext() might be removed even with -O0? */ +#endif +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskCHECK_FOR_STACK_OVERFLOW(); + + /* Before the currently running task is switched out, save its errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + pxCurrentTCB->iTaskErrno = FreeRTOS_errno; + } + #endif + + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + traceTASK_SWITCHED_IN(); + + /* After the new task is switched in, update the global errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = pxCurrentTCB->iTaskErrno; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. The queue that contains the event + list is locked, preventing simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event groups implementation. */ + configASSERT( uxSchedulerSuspended != 0 ); + + /* Store the item value in the event list item. It is safe to access the + event list item here as interrupts won't access the event list item of a + task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + list. It is safe to access the event list here because it is part of an + event group implementation - and interrupts don't access event groups + directly (instead they access them indirectly by pending function calls to + the task level). */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called with the scheduler suspended. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* If the task should block indefinitely then set the block time to a + value that will be recognised as an indefinite delay inside the + prvAddCurrentTaskToDelayedList() function. */ + if( xWaitIndefinitely != pdFALSE ) + { + xTicksToWait = portMAX_DELAY; + } + + traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + be removed as it is known to be the highest priority. Remove the TCB from + the delayed list, and add it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means exclusive access to the event list is guaranteed here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + might be set to the blocked task's time out time. If the task is + unblocked for a reason other than a timeout xNextTaskUnblockTime is + normally left unchanged, because it is automatically reset to a new + value when the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter sleep mode + at the earliest possible time - so reset xNextTaskUnblockTime here to + ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +{ +TCB_t *pxUnblockedTCB; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event flags implementation. */ + configASSERT( uxSchedulerSuspended != pdFALSE ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + event flags. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( pxEventListItem ); + + /* Remove the task from the delayed list and add it to the ready list. The + scheduler is suspended so interrupts will not be accessing the ready + lists. */ + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The unblocked task has a priority above that of the calling task, so + a context switch is required. This function is called with the + scheduler suspended so xYieldPending is set so the context switch + occurs immediately that the scheduler is resumed (unsuspended). */ + xYieldPending = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + taskENTER_CRITICAL(); + { + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* For internal use only as it does not use a critical section. */ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) + { + /* The delay was aborted, which is not the same as a time out, + but has the same result. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + xReturn = pdTRUE; + } + else + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + if( *pxTicksToWait == portMAX_DELAY ) + { + /* If INCLUDE_vTaskSuspend is set to 1 and the block time + specified is the maximum block time then the task should block + indefinitely, and therefore never time out. */ + xReturn = pdFALSE; + } + else + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which + vTaskSetTimeout() was called, but has also overflowed since + vTaskSetTimeOut() was called. It must have wrapped all the way + around and gone past again. This passed since vTaskSetTimeout() + was called. */ + xReturn = pdTRUE; + } + else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= xElapsedTime; + vTaskInternalSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + *pxTicksToWait = 0; + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t const *pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) + { + TCB_t * pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE + SCHEDULER IS STARTED. **/ + + /* In case a task that has a secure context deletes itself, in which case + the idle task is responsible for deleting the task's secure context, if + any. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + for( ;; ) + { + /* See if any tasks have deleted themselves - if so then the idle task + is responsible for freeing the deleted task's TCB and stack. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + /* EST: Use user hook name */ + extern void configUSE_IDLE_HOOK_NAME( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + configUSE_IDLE_HOOK_NAME(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + #if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + if (configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME()) /* ask application if it shall enter tickless idle mode */ + #endif + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + /* Define the following macro to set xExpectedIdleTime to 0 + if the application does not want + portSUPPRESS_TICKS_AND_SLEEP() to be called. */ + configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE != 0 ) + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + /* If all the tasks are in the suspended list (which might mean they + have an infinite block time rather than actually being suspended) + then it is safe to turn all clocks off and just wait for external + interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return eReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + } + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void *pvReturn = NULL; + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) + { + TCB_t *pxTCB; + + /* If null is passed in here then we are modifying the MPU settings of + the calling task. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + + /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + TCB_t *pxTCB; + + /* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL() + being called too often in the idle task. */ + while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) + { + taskENTER_CRITICAL(); + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + --uxCurrentNumberOfTasks; + --uxDeletedTasksWaitingCleanUp; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + #endif /* INCLUDE_vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + + void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) + { + TCB_t *pxTCB; + + /* xTask is NULL then get the state of the calling task. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; + pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName [ 0 ] ); + pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; + pxTaskStatus->pxStackBase = pxTCB->pxStack; + pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; + } + #else + { + pxTaskStatus->uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatus->ulRunTimeCounter = 0; + } + #endif + + /* Obtaining the task state is a little fiddly, so is only done if the + value of eState passed into this function is eInvalid - otherwise the + state is just set to whatever is passed in. */ + if( eState != eInvalid ) + { + if( pxTCB == pxCurrentTCB ) + { + pxTaskStatus->eCurrentState = eRunning; + } + else + { + pxTaskStatus->eCurrentState = eState; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a + chance it is actually just blocked indefinitely - so really + it should be reported as being in the Blocked state. */ + if( eState == eSuspended ) + { + vTaskSuspendAll(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatus->eCurrentState = eBlocked; + } + } + ( void ) xTaskResumeAll(); + } + } + #endif /* INCLUDE_vTaskSuspend */ + } + } + else + { + pxTaskStatus->eCurrentState = eTaskGetState( pxTCB ); + } + + /* Obtaining the stack space takes some time, so the xGetFreeStackSpace + parameter is provided to allow it to be skipped. */ + if( xGetFreeStackSpace != pdFALSE ) + { + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); + } + #else + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); + } + #endif + } + else + { + pxTaskStatus->usStackHighWaterMark = 0; + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) + { + configLIST_VOLATILE TCB_t *pxNextTCB, *pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Populate an TaskStatus_t structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of TaskStatus_t in task.h for the + meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + uxTask++; + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( configSTACK_DEPTH_TYPE ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + same except for their return type. Using configSTACK_DEPTH_TYPE allows the + user to determine the return type. It gets around the problem of the value + overflowing on 8-bit types without breaking backward compatibility for + applications that expect an 8-bit return type. */ + configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + configSTACK_DEPTH_TYPE uxReturn; + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are + the same except for their return type. Using configSTACK_DEPTH_TYPE + allows the user to determine the return type. It gets around the + problem of the value overflowing on 8-bit types without breaking + backward compatibility for applications that expect an 8-bit return + type. */ + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up + to the task to free any memory allocated at the application level. */ + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) + { + /* The task can only have been allocated dynamically - free both + the stack and TCB. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* The task could have been allocated statically or dynamically, so + check what was statically allocated before trying to free the + memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) + { + /* Both the stack and TCB were allocated dynamically, so both + must be freed. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ +TCB_t *pxTCB; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set xNextTaskUnblockTime to + the maximum possible value so it is extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + ( pxTCB ) = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxMutexHolderTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. _RB_ Is this still + needed as interrupts can no longer use mutexes? */ + if( pxMutexHolder != NULL ) + { + /* If the holder of the mutex has a priority below the priority of + the task attempting to obtain the mutex then it will temporarily + inherit the priority of the task attempting to obtain the mutex. */ + if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + priority. Only reset the event list item value if the value is + not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need + to be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxMutexHolderTCB ); +#else + prvAddTaskToReadyList( pxMutexHolderTCB ); +#endif + } + else + { + /* Just inherit the priority. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); + + /* Inheritance occurred. */ + xReturn = pdTRUE; + } + else + { + if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) + { + /* The base priority of the mutex holder is lower than the + priority of the task attempting to take the mutex, but the + current priority of the mutex holder is not lower than the + priority of the task attempting to take the mutex. + Therefore the mutex holder must have already inherited a + priority, but inheritance would have occurred if that had + not been the case. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + /* A task can only have an inherited priority if it holds the mutex. + If the mutex is held by a task then it cannot be given from an + interrupt, and if a mutex is given by the holding task then it must + be the running state task. */ + configASSERT( pxTCB == pxCurrentTCB ); + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + /* Has the holder of the mutex inherited the priority of another + task? */ + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* A task can only have an inherited priority if it holds + the mutex. If the mutex is held by a task then it cannot be + given from an interrupt, and if a mutex is given by the + holding task then it must be the running state task. Remove + the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the + new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + any other purpose if this task is running, and it must be + running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + + /* Return true to indicate that a context switch is required. + This is only actually required in the corner case whereby + multiple mutexes were held and the mutexes were given back + in an order different to that in which they were taken. + If a context switch did not occur when the first mutex was + returned, even if a task was waiting on it, then a context + switch should occur when the last mutex is returned whether + a task is waiting on it or not. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) + { + TCB_t * const pxTCB = pxMutexHolder; + UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse; + const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1; + + if( pxMutexHolder != NULL ) + { + /* If pxMutexHolder is not NULL then the holder must hold at least + one mutex. */ + configASSERT( pxTCB->uxMutexesHeld ); + + /* Determine the priority to which the priority of the task that + holds the mutex should be set. This will be the greater of the + holding task's base priority and the priority of the highest + priority task that is waiting to obtain the mutex. */ + if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask ) + { + uxPriorityToUse = uxHighestPriorityWaitingTask; + } + else + { + uxPriorityToUse = pxTCB->uxBasePriority; + } + + /* Does the priority need to change? */ + if( pxTCB->uxPriority != uxPriorityToUse ) + { + /* Only disinherit if no other mutexes are held. This is a + simplification in the priority inheritance implementation. If + the task that holds the mutex is also holding other mutexes then + the other mutexes may have caused the priority inheritance. */ + if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld ) + { + /* If a task has timed out because it already holds the + mutex it was trying to obtain then it cannot of inherited + its own priority. */ + configASSERT( pxTCB != pxCurrentTCB ); + + /* Disinherit the priority, remembering the previous + priority to facilitate determining the subject task's + state. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + uxPriorityUsedOnEntry = pxTCB->uxPriority; + pxTCB->uxPriority = uxPriorityToUse; + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the running task is not the task that holds the mutex + then the task that holds the mutex could be in either the + Ready, Blocked or Suspended states. Only remove the task + from its current state list if it is in the Ready state as + the task's priority is going to change and there is one + Ready list per priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + function so assert() if it is being called from an interrupt + context. Only API functions that end in "FromISR" can be used in an + interrupt. Only assert if the critical nesting count is 1 to + protect against recursive calls if the assert function also uses a + critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) + { + size_t x; + + /* Start by copying the entire string. */ + strcpy( pcBuffer, pcTaskName ); + + /* Pad the end of the string with spaces to ensure columns line up when + printed out. */ + for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + { + pcBuffer[ x ] = ' '; + } + + /* Terminate. */ + pcBuffer[ x ] = ( char ) 0x00; + + /* Return the new end of string. */ + return &( pcBuffer[ x ] ); + } +#endif /* << EST not used */ +#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskList( char * pcWriteBuffer, size_t bufSize ) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! if + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eRunning: cStatus = tskRUNNING_CHAR; + break; + + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + case eInvalid: /* Fall through. */ + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = ( char ) 0x00; + break; + } + +#if 0 /* << EST */ + /* Write the task name to the string, padding with spaces so it + can be printed in tabular form more easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + /* Write the rest of the string. */ + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#else /* << EST */ + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)cStatus); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].uxCurrentPriority); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].usStackHighWaterMark); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].xTaskNumber); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\r\n"); +#endif + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + uint32_t ulTotalTime, ulStatsAsPercentage; + + #if( configUSE_TRACE_FACILITY != 1 ) + { + #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). + } + #endif + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! If + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0UL ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + +#if 0 /* << EST */ + /* Write the task name to the string, padding with + spaces so it can be printed in tabular form more + easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); +#else + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); +#endif + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, ulStatsAsPercentage); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"%\r\n"); +#endif + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t<1%\r\n"); +#endif + } + #endif + } +#if 0 /* << EST */ + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#endif + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ +TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + TaskHandle_t pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) + { + uint32_t ulReturn; + + taskENTER_CRITICAL(); + { + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue == 0UL ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_TAKE_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_TAKE(); + ulReturn = pxCurrentTCB->ulNotifiedValue; + + if( ulReturn != 0UL ) + { + if( xClearCountOnExit != pdFALSE ) + { + pxCurrentTCB->ulNotifiedValue = 0UL; + } + else + { + pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + set by the notifying task or interrupt. This can be used to + clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry; + + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_WAIT_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_WAIT(); + + if( pulNotificationValue != NULL ) + { + /* Output the current notification value, which may or may not + have changed. */ + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue; + } + + /* If ucNotifyValue is set then either the task never entered the + blocked state (because a notification was already pending) or the + task unblocked because of a notification. Otherwise the task + unblocked because of a timeout. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* A notification was not received. */ + xReturn = pdFALSE; + } + else + { + /* A notification was already pending or a notification was + received while the task was waiting. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit; + xReturn = pdTRUE; + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) + { + TCB_t * pxTCB; + BaseType_t xReturn = pdPASS; + uint8_t ucOriginalNotifyState; + + configASSERT( xTaskToNotify ); + pxTCB = xTaskToNotify; + + taskENTER_CRITICAL(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction: + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + + break; + } + + traceTASK_NOTIFY(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + xNextTaskUnblockTime might be set to the blocked task's time + out time. If the task is unblocked for a reason other than + a timeout xNextTaskUnblockTime is normally left unchanged, + because it will automatically get reset to a new value when + the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter + sleep mode at the earliest possible time - so reset + xNextTaskUnblockTime here to ensure it is updated at the + earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + BaseType_t xReturn = pdPASS; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction : + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + break; + } + + traceTASK_NOTIFY_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter to an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + /* 'Giving' is equivalent to incrementing a count in a counting + semaphore. */ + ( pxTCB->ulNotifiedValue )++; + + traceTASK_NOTIFY_GIVE_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter in an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ + +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + BaseType_t xReturn; + + /* If null is passed in here then it is the calling task that is having + its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) + { + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t xTaskGetIdleRunTimeCounter( void ) + { + return xIdleTaskHandle->ulRunTimeCounter; + } +#endif +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) +{ +TickType_t xTimeToWake; +const TickType_t xConstTickCount = xTickCount; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + /* About to enter a delayed list, so ensure the ucDelayAborted flag is + reset to pdFALSE so it can be detected as having been set to pdTRUE + when the task leaves the Blocked state. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Remove the task from the ready list before adding it to the blocked list + as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); /*lint !e931 pxCurrentTCB cannot change as it is the calling task. pxCurrentTCB->uxPriority and uxTopReadyPriority cannot change as called with scheduler suspended or in a critical section. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure it is not woken by a timing event. It will block + indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + kernel will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow + list. */ + traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); /* << EST */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list + is used. */ + traceMOVED_TASK_TO_DELAYED_LIST(); /* << EST */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the + head of the list of blocked tasks then xNextTaskUnblockTime + needs to be updated too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the kernel + will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ + ( void ) xCanBlockIndefinitely; + } + #endif /* INCLUDE_vTaskSuspend */ +} + +/* Code below here allows additional code to be inserted into this source file, +especially where access to file scope functions and data is needed (for example +when performing module tests). */ + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + + +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) /* << EST test on trace */ + + #include "freertos_tasks_c_additions.h" + + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + static void freertos_tasks_c_additions_init( void ) + { + FREERTOS_TASKS_C_ADDITIONS_INIT(); + } + #endif + +#endif + +#if 1 /* << EST: additional functionality to iterathe through task handles. */ +static void prvCollectTaskHandlesWithinSingleList( List_t *pxList, TaskHandle_t taskHandleArray[], UBaseType_t noTaskHandlesInArray, UBaseType_t *idxCounter) +{ + TCB_t *pxNextTCB, *pxFirstTCB; + + /* This function is called with the scheduler suspended. */ + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + if (*idxCounter ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Search the suspended list. */ + prvCollectTaskHandlesWithinSingleList( &xSuspendedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Search the deleted list. */ + prvCollectTaskHandlesWithinSingleList( &xTasksWaitingTermination, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + } + ( void ) xTaskResumeAll(); + return idxCounter; +} + +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated) +{ + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the that + called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); +#if ( portSTACK_GROWTH > 0 ) + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxEndOfStack; +#elif (configRECORD_STACK_HIGH_ADDRESS == 1) + *ppxStart = pxTCB->pxEndOfStack; + *ppxEnd = pxTCB->pxStack; +#else /* no stack end information, return a zero size */ + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxStack; +#endif + *ppxTopOfStack = (StackType_t*)pxTCB->pxTopOfStack; +#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + *pucStaticallyAllocated = pxTCB->ucStaticallyAllocated; +#elif (configSUPPORT_STATIC_ALLOCATION && !configSUPPORT_DYNAMIC_ALLOCATION) /* only static allocation */ + *pucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; +#else /* only configSUPPORT_DYNAMIC_ALLOCATION */ + *pucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; +#endif + } + taskEXIT_CRITICAL(); +} +#endif /* << EST end */ + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/timers.c b/Projects/tinyK20_SolderDispenser/Generated_Code/timers.c new file mode 100644 index 0000000..1199d32 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/timers.c @@ -0,0 +1,1111 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( TickType_t ) 0U + +/* The name assigned to the timer service task. This can be overridden by +defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configTIMER_SERVICE_TASK_NAME + #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" +#endif + +/* Bit definitions used in the ucStatus member of a timer structure. */ +#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) +#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) +#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + +#define TIMER_LEGACY_API (1) /* << EST: needed to have TAD working */ + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ +#if TIMER_LEGACY_API /* << EST */ + UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ +#endif + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ +} xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t +name below to enable the use of older kernel aware debuggers. */ +typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. +Two types of message can be queued - messages that manipulate a software timer, +and messages that request the execution of a non-timer related callback. The +two message types are defined in two separate structures, xTimerParametersType +and xCallbackParametersType respectively. */ +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier +that is used to determine which message type is valid. */ +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access these lists. +xActiveTimerList1 and xActiveTimerList2 could be at function scope but that +breaks some kernel aware debuggers, and debuggers that reply on removing the +static qualifier. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; +PRIVILEGED_DATA static List_t *pxCurrentTimerList; +PRIVILEGED_DATA static List_t *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; +PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + /* If static allocation is supported then the application must provide the + following callback function - which enables the application to optionally + provide the memory that will be used by the timer task as the task's stack + and TCB. */ + extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + +#endif + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * Called after a Timer_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +BaseType_t xTimerCreateTimerTask( void ) +{ +BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxTimerTaskTCBBuffer = NULL; + StackType_t *pxTimerTaskStackBuffer = NULL; + uint32_t ulTimerTaskStackSize; + + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + ulTimerTaskStackSize, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + pxTimerTaskStackBuffer, + pxTimerTaskTCBBuffer ); + + if( xTimerTaskHandle != NULL ) + { + xReturn = pdPASS; + } + } + #else + { + xReturn = xTaskCreate( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + configTIMER_TASK_STACK_DEPTH, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + &xTimerTaskHandle ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) + { + Timer_t *pxNewTimer; + + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */ + + if( pxNewTimer != NULL ) + { + /* Status is thus far zero as the timer is not created statically + and has not been started. The autoreload bit may get set in + prvInitialiseNewTimer. */ + pxNewTimer->ucStatus = 0x00; + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) + { + Timer_t *pxNewTimer; + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTimer_t equals the size of the real timer + structure. */ + volatile size_t xSize = sizeof( StaticTimer_t ); + configASSERT( xSize == sizeof( Timer_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ + configASSERT( pxTimerBuffer ); + pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */ + + if( pxNewTimer != NULL ) + { + /* Timers can be created statically or dynamically so note this + timer was created statically in case it is later deleted. The + autoreload bit may get set in prvInitialiseNewTimer(). */ + pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; + + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) +{ + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function + parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + if( uxAutoReload != pdFALSE ) + { + pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } +#if TIMER_LEGACY_API /* << EST */ + pxNewTimer->uxAutoReload = uxAutoReload; +#endif + traceTIMER_CREATE( pxNewTimer ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) +{ +BaseType_t xReturn = pdFAIL; +DaemonTaskMessage_t xMessage; + + configASSERT( xTimer ); + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) +{ + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->xTimerPeriodInTicks; +} +/*-----------------------------------------------------------*/ + +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) +{ +Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + taskENTER_CRITICAL(); + { + if( uxAutoReload != pdFALSE ) + { + pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD; + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) +{ +Timer_t * pxTimer = xTimer; +TickType_t xReturn; + + configASSERT( xTimer ); + xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->pcTimerName; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) +{ +BaseType_t xResult; +Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* The timer is inserted into a list using a time relative to anything + other than the current time. It will therefore be inserted into the + correct list relative to the time this task thinks it is now. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + mtCOVERAGE_TEST_MARKER(); + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvTimerTask, pvParameters ) +{ +TickType_t xNextExpireTime; +BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + { + extern void vApplicationDaemonTaskStartupHook( void ); + + /* Allow the application writer to execute some code in the context of + this task at the point the task starts executing. This is useful if the + application includes initialisation code that would benefit from + executing after the scheduler has been started. */ + vApplicationDaemonTaskStartupHook(); + } + #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) +{ +TickType_t xTimeNow; +BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + if( xListWasEmpty != pdFALSE ) + { + /* The current timer list is empty - is the overflow list + also empty? */ + xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); + } + + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the + block time to expire. If a command arrived between the + critical section being exited and this yield then the yield + will not cause the task to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) +{ +TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) +{ +TickType_t xTimeNow; +PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) +{ +BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +DaemonTaskMessage_t xMessage; +Timer_t *pxTimer; +BaseType_t xTimerListsWereSwitched, xResult; +TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + case tmrCOMMAND_START_FROM_ISR : + case tmrCOMMAND_RESET : + case tmrCOMMAND_RESET_FROM_ISR : + case tmrCOMMAND_START_DONT_TRACE : + /* Start or restart a timer. */ + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + timer list. Process it now. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + traceTIMER_EXPIRED( pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + break; + + case tmrCOMMAND_STOP : + case tmrCOMMAND_STOP_FROM_ISR : + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + break; + + case tmrCOMMAND_CHANGE_PERIOD : + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + be longer or shorter than the old one. The command time is + therefore set to the current time, and as the period cannot + be zero the next expiry time can only be in the future, + meaning (unlike for the xTimerStart() case above) there is + no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* The timer has already been removed from the active list, + just free up the memory if the memory was dynamically + allocated. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) + { + vPortFree( pxTimer ); + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + } + #else + { + /* If dynamic allocation is not enabled, the memory + could not have been dynamically allocated. So there is + no need to free the memory - just mark the timer as + "not active". */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default : + /* Don't expect to get here. */ + break; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( void ) +{ +TickType_t xNextExpireTime, xReloadTime; +List_t *pxTemp; +Timer_t *pxTimer; +BaseType_t xResult; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The timer queue is allocated statically in case + configSUPPORT_DYNAMIC_ALLOCATION is 0. */ + static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + + xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); + } + #else + { + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + } + #endif + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) +{ +BaseType_t xReturn; +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) +{ +Timer_t * const pxTimer = xTimer; +void *pvReturn; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pvReturn = pxTimer->pvTimerID; + } + taskEXIT_CRITICAL(); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) +{ +Timer_t * const pxTimer = xTimer; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pxTimer->pvTimerID = pvNewID; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* This function can only be called after a timer has been created or + after the scheduler has been started because, until then, the timer + queue does not exist. */ + configASSERT( xTimerQueue ); + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) + { + return ( ( Timer_t * ) xTimer )->uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) + { + ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/timers.h b/Projects/tinyK20_SolderDispenser/Generated_Code/timers.h new file mode 100644 index 0000000..a6f9324 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/timers.h @@ -0,0 +1,1296 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); + * + * Updates a timer to be either an autoreload timer, in which case the timer + * automatically resets itself each time it expires, or a one shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/types.h b/Projects/tinyK20_SolderDispenser/Generated_Code/types.h new file mode 100644 index 0000000..836ec8d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/types.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file types.h + * + * @author + * + * @version + * + * @date + * + * @brief The file contains definitions of datatypes. + * + *****************************************************************************/ + + +#ifndef _TYPES_H +#define _TYPES_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define LSB(a) ((a)._byte.byte0) +#define MSB(a) ((a)._byte.byte1) + +#define LOWER_LSB(a) ((a)._byte.byte0) +#define LOWER_MSB(a) ((a)._byte.byte1) +#define UPPER_LSB(a) ((a)._byte.byte2) +#define UPPER_MSB(a) ((a)._byte.byte3) + +#define _PTR_ * +#define _CODE_PTR_ * + +#ifndef TRUE +#define FALSE 0 +#define TRUE 1 +#endif + +#define BYTESWAP16(x) (uint_16)((((x) & 0xFF00) >> 0x8) | (((x) & 0xFF) << 0x8)) +#define BYTESWAP32(val) (uint_32)((BYTESWAP16((uint_32)(val) & (uint_32)0xFFFF) << 0x10) | \ + (BYTESWAP16((uint_32)((val) >> 0x10)))) + +#ifdef __HIWARE__ /* define macros used below to avoid warnings for S08 */ + #define __ORDER_LITTLE_ENDIAN__ 0 + #define __BYTE_ORDER__ 1 + #define BIG_ENDIAN +#endif + +#ifdef CPU_LITTLE_ENDIAN /* << EST: defined by Processor Expert CPU.h for Kinetis devices (but NOT in for SDK 1.x!) */ + #ifndef LITTLE_ENDIAN /* might be defined already on the compiler command line? */ + #define LITTLE_ENDIAN + #endif +#elif defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* GNU/gcc provides these macros */ + #define LITTLE_ENDIAN +#endif + +#ifndef LITTLE_ENDIAN +#define ieee_htons(x) (uint_16)(x) +#define ieee_htonl(x) (uint_32)(x) +#define ieee_ntohs(x) (uint_16)(x) +#define ieee_ntohl(x) (uint_32)(x) +#else +#define ieee_htons(x) BYTESWAP16(x) +#define ieee_htonl(x) BYTESWAP32(x) +#define ieee_ntohs(x) BYTESWAP16(x) +#define ieee_ntohl(x) BYTESWAP32(x) +#endif + +#define UNUSED(x) (void)x; +/****************************************************************************** + * Types + *****************************************************************************/ +typedef void _PTR_ pointer; /* Machine representation of a pointer */ +typedef unsigned char uint_8; /* 8-bit*/ +typedef signed char int_8; /* 8-bit*/ + +typedef unsigned short uint_16; /* 16-bit*/ +typedef signed short int_16; /* 16-bit*/ + +typedef unsigned long uint_32; /* 32-bit*/ +typedef signed long int_32; /* 32-bit*/ + +typedef unsigned char boolean; /* 8-bit*/ + +typedef uint_8* uint_8_ptr; /* ptr to 8-bit*/ +typedef uint_16* uint_16_ptr; /* ptr to 16-bit */ +typedef uint_32* uint_32_ptr; /* ptr to 32-bit*/ + +typedef uint_8_ptr uchar_ptr; /* ptr to 8-bit*/ + + +/****************************************************************************** + * Global Functions - None + *****************************************************************************/ + +#endif + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_bdt_kinetis.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_bdt_kinetis.h new file mode 100644 index 0000000..d73c85d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_bdt_kinetis.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_bdt_kinetis.h + * + * @author + * + * @version + * + * @date Jun-05-2009 + * + * @brief The file contains definitions of Buffer Descriptor Table. + * + *****************************************************************************/ + +#ifndef _USBBDT_H +#define _USBBDT_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +/* Buffer Descriptor Status Register Initialization Parameters */ +#define _BDTSTALL (0x04) /* Buffer Stall enable */ +#define _DATA0 (0x00) /* DATA0 packet expected next */ +#define _DATA1 (0x40) /* DATA1 packet expected next */ +#define _DTS (0x08) /* DTS Mask */ +#define _SIE (0x80) /* SIE owns buffer */ +#define _CPU (0x00) /* CPU owns buffer */ +#define _KEEP (0x20) /* keep bit */ + +#define MAX_BDT_INDEX (64) /* Maximum BDT Indexes */ + + +/****************************************************************************** + * Types + *****************************************************************************/ + /* This structure is an exact replica of the BDT MAP in the USB RAM + The BDT_STAT defines the stat byte of the buffer descriptor vector. + McuCtlBit structure defines the bits that have a meaning from CPU + point of view.SieCtlBit structure defines the bits that have a + meaning from USB controller point of view. + */ + +#if defined(__CWCC__) +#pragma align_array_members on +#endif +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) +typedef struct _MCU_CTL_BIT{ + uint_8 :1; + uint_8 :1; + uint_8 bdtstall:1; /* Buffer Stall Enable */ + uint_8 dts:1; /* Data Toggle Synch Enable */ + uint_8 keep:1; /* Address Increment Disable */ + uint_8 ninc:1; /* BD Keep Enable */ + uint_8 data:1; /* Data Toggle Synch Value */ + uint_8 own:1; /* USB Ownership */ +}MCU_CTL_BIT; /* read Stat */ + +typedef struct _SIE_CTL_BIT{ + uint_8 :1; + uint_8 :1; + uint_8 pid0:1; /* Packet Identifier bit 0 */ + uint_8 pid1:1; /* Packet Identifier bit 1 */ + uint_8 pid2:1; /* Packet Identifier bit 2 */ + uint_8 pid3:1; /* Packet Identifier bit 3 */ + uint_8 :1; + uint_8 own:1; +}SIE_CTL_BIT; /* write Stat */ + +typedef struct _REC_PID{ + uint_8 :2; + uint_8 pid:4; /* Packet Identifier */ + uint_8 :2; +}REC_PID; + +typedef union _BD_STAT +{ + uint_8 _byte; + MCU_CTL_BIT McuCtlBit; + SIE_CTL_BIT SieCtlBit; + REC_PID RecPid; +} BD_STAT; /* Buffer Descriptor Status Register */ + +typedef struct _BUFF_DSC +{ + BD_STAT Stat; + uint_8 reserved1; + uint_16 cnt; /* Count of bytes receieved or sent */ + /* six MSB bits are reserved ones */ + uint_32 addr; /* Buffer Address */ +} BUFF_DSC, *P_BUFF_DSC; /* Buffer Descriptor Table */ + +typedef struct _g_bdtmap { + + BUFF_DSC ep_dsc[MAX_BDT_INDEX]; /* Endpoint Descriptor */ +}BDTMAP; +#if defined(__CWCC__) +#pragma align_array_members off +#pragma options align=reset +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#else /* e.g. gcc */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#endif +/****************************************************************************** + * Global Functions - None + *****************************************************************************/ + +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.c new file mode 100644 index 0000000..82388e0 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.c @@ -0,0 +1,809 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack CDC layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_cdc.h" /* USB CDC Class Header File */ +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef _MC9S08JS16_H +#pragma DATA_SEG APP_DATA +#endif + +/* CDC Class Callback Function Pointer */ +static USB_CLASS_CALLBACK g_cdc_class_callback = NULL; + +/* CDC Class Vendor Callback Function Pointer */ +static USB_REQ_FUNC g_vendor_req_callback = NULL; + +/* CDC endpoint info array */ +#ifndef COMPOSITE_DEV +static USB_CLASS_CDC_ENDPOINT g_cdc_ep[CDC_DESC_ENDPOINT_COUNT]; +#else +static USB_CLASS_CDC_ENDPOINT g_cdc_ep[COMPOSITE_DESC_ENDPOINT_COUNT]; +#endif +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +#if CIC_NOTIF_ELEM_SUPPORT +void USB_Class_CDC_Service_Cic_Notify(PTR_USB_DEV_EVENT_STRUCT event); +#endif +#if !DIC_ISOCHRONOUS_SETTING +void USB_Class_CDC_Service_Dic_Bulk_In(PTR_USB_DEV_EVENT_STRUCT event); +void USB_Class_CDC_Service_Dic_Bulk_Out(PTR_USB_DEV_EVENT_STRUCT event); +#else +static void USB_Class_CDC_Service_Dic_Iso_In(PTR_USB_DEV_EVENT_STRUCT event); +static void USB_Class_CDC_Service_Dic_Iso_Out(PTR_USB_DEV_EVENT_STRUCT event); +#endif +#ifndef COMPOSITE_DEV +static uint_8 USB_Other_Requests( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +#endif + void USB_Class_CDC_Event( + uint_8 controller_ID, + uint_8 event, + void* val); + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + + /***************************************************************************** + * Local Functions + *****************************************************************************/ +#if CIC_NOTIF_ELEM_SUPPORT +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Cic_Notify + * + * @brief The function is callback function of CIC Notification endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower layer when data on CIC Endpoint is sent + *****************************************************************************/ +void USB_Class_CDC_Service_Cic_Notify ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + break; + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + + if(g_cdc_class_callback != NULL) + { + uint_8 event_type = USB_APP_SEND_COMPLETE; + + if(event->errors != 0) + { + event_type = USB_APP_ERROR; + } + g_cdc_class_callback(event->controller_ID, event_type, + (uint_8*)(&(event->errors))); + } +} +#endif + +#if !DIC_ISOCHRONOUS_SETTING +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Bulk_In + * + * @brief The function is callback function of DIC Bulk In Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC SEND Interface is sent + *****************************************************************************/ +void USB_Class_CDC_Service_Dic_Bulk_In ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT bulk_in_recv; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + bulk_in_recv.data_ptr = event->buffer_ptr; + bulk_in_recv.data_size = event->len; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + break; + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, + (void*)&bulk_in_recv); + } + } +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Bulk_Out + * + * @brief The function is callback function of DIC Bulk Out Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC RECV Interface is received + *****************************************************************************/ +void USB_Class_CDC_Service_Dic_Bulk_Out ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ APP_DATA_STRUCT bulk_out_recv; + + bulk_out_recv.data_ptr = event->buffer_ptr; + bulk_out_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_DATA_RECEIVED, + (void*)&bulk_out_recv); + } + } +} + +#else +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Iso_In + * + * @brief The function is callback function of DIC Isochronous In Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC SEND Interface is sent + *****************************************************************************/ +static void USB_Class_CDC_Service_Dic_Iso_In ( + PTR_USB_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT iso_in_recv; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + { + break; + } + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + + iso_in_recv.data_ptr = event->buffer_ptr; + iso_in_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, + (void*)&iso_in_recv); + } + } +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Iso_Out + * + * @brief This is a callback function of DIC Isochronous Out Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC RECV Interface is received + *****************************************************************************/ +static void USB_Class_CDC_Service_Dic_Iso_Out ( + PTR_USB_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT iso_out_recv; + + iso_out_recv.data_ptr = event->buffer_ptr; + iso_out_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_DATA_RECEIVED, + (void*)&iso_out_recv); + } + } +} +#endif +/**************************************************************************//*! + * + * @name USB_Class_CDC_Event + * + * @brief The function initializes CDC endpoints + * + * @param controller_ID : Controller ID + * @param event : Event Type + * @param val : Pointer to configuration Value + * + * @return None + * + ****************************************************************************** + * + *****************************************************************************/ +void USB_Class_CDC_Event ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 event, /* [IN] Event Type */ + void* val /* [OUT] Pointer to configuration Value */ +) +{ + uint_8 index; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(controller_ID); + + if(event == USB_APP_ENUM_COMPLETE) + { + uint_8 count = 0,ep_count = 0; + uint_8 index_num = 0; + +#ifdef COMPOSITE_DEV + DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr; + CLASS_ARC_STRUCT_PTR dev_class_ptr; + dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID); + for(count = 0; count < dev_arc_ptr->cl_count; count++) + { + dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count]; + /* Initializes sub_classes */ + ep_count = dev_class_ptr->value[0]; + if(dev_class_ptr->class_type == 0x02/*CDC_CC*/) + break; + index_num +=dev_class_ptr->value[0]; + } +#else + ep_count = usb_ep_data->count; +#endif + + for(count=index_num; countep[count]); + (void)_usb_device_deinit_endpoint(&controller_ID, + ep_struct_ptr->ep_num, ep_struct_ptr->direction); + } + + /* intialize all non control endpoints */ + for(count=index_num; countep[count]); + + (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num, + ep_struct->size, ep_struct->direction, ep_struct->type, FALSE); + + /* register callback service for Non Control EndPoints */ + switch(ep_struct->type) + { +#if CIC_NOTIF_ELEM_SUPPORT + case USB_INTERRUPT_PIPE : + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Cic_Notify); + break; +#endif +#if !DIC_ISOCHRONOUS_SETTING + case USB_BULK_PIPE : +#ifdef MULTIPLE_DEVICES + if(ep_struct->direction == USB_RECV) + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Bulk_Out); + } + else + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Bulk_In); + } +#endif + break; +#else + case USB_ISOCHRONOUS_PIPE : + if(ep_struct->direction == USB_RECV) + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Iso_Out); + } + else + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Iso_In); + } + break; +#endif + default: + break; + } + /* set the EndPoint Status as Idle in the device layer */ + (void)_usb_device_set_status(&controller_ID, + (uint_8)(USB_STATUS_ENDPOINT | ep_struct->ep_num | + (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)), + (uint_8)USB_STATUS_IDLE); + } + } + else if(event == USB_APP_BUS_RESET) + { +#if IMPLEMENT_QUEUING + for(index = 0; index < usb_ep_data->count; index++) + { + g_cdc_ep[index].bin_consumer = 0x00; + g_cdc_ep[index].bin_producer = 0x00; + } +#endif + } + if(g_cdc_class_callback != NULL) + { + g_cdc_class_callback(controller_ID, event, val); + } +} + +/**************************************************************************//*! + * + * @name USB_Other_Requests + * + * @brief The function provides flexibilty to add class and vendor specific + * requests + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data: : Data to be send back + * @param size: : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * Handles CDC Class requests and forwards vendor specific request to the + * application + *****************************************************************************/ +#ifndef COMPOSITE_DEV +static uint_8 USB_Other_Requests +#else +uint_8 USB_CDC_Other_Requests +#endif +( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet,/* [IN] Pointer to Setup Packet Received */ + uint_8_ptr *data, /* [OUT] Pointer to Data Buffer to be sent */ + USB_PACKET_SIZE *size /* [OUT] Size of Data buffer */ +) +{ + uint_8 status = USBERR_INVALID_REQ_TYPE; + if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_CLASS) + { + /* class request so handle it here */ + status=USB_OK; + + /* call for class/subclass specific requests */ + switch(setup_packet->request) + { + case SEND_ENCAPSULATED_COMMAND : + /* Add code to transfer Request and Acknowledgement */ + *size=0; + break; + case GET_ENCAPSULATED_RESPONSE : + /* + Add code for handling Transfer Response/Requests and + Notification + */ + *size=0; + break; + case SET_COMM_FEATURE : + status = USB_Class_CDC_PSTN_Set_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case GET_COMM_FEATURE : + status = USB_Class_CDC_PSTN_Get_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case CLEAR_COMM_FEATURE : /* Verify this implementation */ + *size = COMM_FEATURE_DATA_SIZE; + **data = 0x00; *(++(*data)) = 0x00;/* clear both feature bytes */ + status = USB_Class_CDC_PSTN_Set_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case GET_LINE_CODING : + status = USB_Class_CDC_PSTN_Get_Line_Coding(controller_ID, + setup_packet, data, size); + break; + case SET_LINE_CODING : + status = USB_Class_CDC_PSTN_Set_Line_Coding(controller_ID, + setup_packet, data, size); + break; + case SET_CONTROL_LINE_STATE : + status = USB_Class_CDC_PSTN_Set_Ctrl_Line_State(controller_ID, + setup_packet, data, size); + break; + case SEND_BREAK : + status = USB_Class_CDC_PSTN_Send_Break(controller_ID, + setup_packet, data, size); + break; + default: + *size=0; + break; + } + } + else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_VENDOR) + { + /* vendor specific request */ + if(g_vendor_req_callback != NULL) + { + status = g_vendor_req_callback(controller_ID, setup_packet, data, + size); + } + } + return status; +} + + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Class_CDC_Init + * + * @brief The function initializes the Device and Controller layer + * + * @param controller_ID: Controller ID + * @param cdc_class_callback: CDC Class Callback + * @param vendor_req_callback: vendor specific class request callback + * @param param_callback: PSTN Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * This function initializes the CDC Class layer and layers it is dependent upon + *****************************************************************************/ +uint_8 USB_Class_CDC_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK cdc_class_callback, /* [IN] CDC Class Callback */ + USB_REQ_FUNC vendor_req_callback, /* [IN] Vendor Request Callback */ + USB_CLASS_CALLBACK pstn_callback, /* [IN] PSTN Callback */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ + uint_8 index,status = USB_OK; + USB_ENDPOINTS *usb_ep_data = + (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID); +#ifndef COMPOSITE_DEV + /* Initialize the device layer*/ + status = _usb_device_init(controller_ID, NULL, + (uint_8)(usb_ep_data->count+1), bVregEn); + /* +1 is for Control Endpoint */ + + if(status == USB_OK) + { + /* Initialize the generic class functions */ + status = USB_Class_Init(controller_ID,USB_Class_CDC_Event, + USB_Other_Requests); +#endif +#if IMPLEMENT_QUEUING + for(index = 0; index < usb_ep_data->count; index++) + { + g_cdc_ep[index].endpoint = usb_ep_data->ep[index].ep_num; + g_cdc_ep[index].type = usb_ep_data->ep[index].type; + g_cdc_ep[index].bin_consumer = 0x00; + g_cdc_ep[index].bin_producer = 0x00; + } +#endif +#if PSTN_SUBCLASS_NOTIF_SUPPORT + /* Initialize the pstn subclass functions */ + status = USB_Class_CDC_Pstn_Init(controller_ID,pstn_callback); +#endif + if(status == USB_OK) + { + /* save the callback pointer */ + g_cdc_class_callback = cdc_class_callback; + + /* save the callback pointer */ + g_vendor_req_callback = vendor_req_callback; + } +#ifndef COMPOSITE_DEV + } +#endif + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_DeInit + * + * @brief The function de-initializes the Device and Controller layer + * + * @param controller_ID : Controller ID + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + *This function de-initializes the CDC Class layer + *****************************************************************************/ +uint_8 USB_Class_CDC_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 status = USB_OK; +#ifdef COMPOSITE_DEV + UNUSED(controller_ID) +#endif + /* save the callback pointer */ + g_cdc_class_callback = NULL; + + /* free the vendor request callback pointer */ + g_vendor_req_callback = NULL; + +#ifndef COMPOSITE_DEV + /* call common class deinit function */ + status = USB_Class_DeInit(controller_ID); + + if(status == USB_OK) + /* Call device deinit function */ + status = _usb_device_deinit(); +#endif + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Send_Data + * + * @brief This function is used to send data from CDC Class over send endpoints + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param app_buff : Buffer to send + * @param size : Length of the transfer + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Helper function. Sends DATA over CIC and DIC Interfaces to Host + *****************************************************************************/ +uint_8 USB_Class_CDC_Send_Data ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8_ptr app_buff, /* Pointer to Application Buffer */ + USB_PACKET_SIZE size /* Size of Application Buffer */ +) +{ + uint_8 status = USB_OK; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(controller_ID); + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == ep_num) + { + break; + } + } + + producer = g_cdc_ep[index].bin_producer; + consumer = g_cdc_ep[index].bin_consumer; + + if(((uint_8)(producer - consumer)) != (uint_8)(MAX_QUEUE_ELEMS)) + { + /* the bin is not full*/ + + uint_8 queue_num = (uint_8)(producer % MAX_QUEUE_ELEMS); + + /* put all send request parameters in the endpoint data structure */ + g_cdc_ep[index].queue[queue_num].controller_ID = controller_ID; + g_cdc_ep[index].queue[queue_num].channel = ep_num; + g_cdc_ep[index].queue[queue_num].app_data.data_ptr = app_buff; + g_cdc_ep[index].queue[queue_num].app_data.data_size = size; + + /* increment producer bin by 1*/ + g_cdc_ep[index].bin_producer = ++producer; + + if((uint_8)(producer - consumer) == (uint_8)1) + { +#endif + status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size); +#if IMPLEMENT_QUEUING + } + } + else /* bin is full */ + { + status = USBERR_DEVICE_BUSY; + } +#endif + return status; +} + +/* EOF */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.h new file mode 100644 index 0000000..952d141 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc.h @@ -0,0 +1,202 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack CDC class layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_CDC_H +#define _USB_CDC_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_descriptor.h" +#include "usb_class.h" +#include "usb_cdc_pstn.h" +#include "usb_devapi.h" +#ifdef COMPOSITE_DEV +#include "usb_composite.h" +#endif + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +/* Class specific request Codes */ +#define SEND_ENCAPSULATED_COMMAND (0x00) +#define GET_ENCAPSULATED_RESPONSE (0x01) +#define SET_COMM_FEATURE (0x02) +#define GET_COMM_FEATURE (0x03) +#define CLEAR_COMM_FEATURE (0x04) +#define SET_AUX_LINE_STATE (0x10) +#define SET_HOOK_STATE (0x11) +#define PULSE_SETUP (0x12) +#define SEND_PULSE (0x13) +#define SET_PULSE_TIME (0x14) +#define RING_AUX_JACK (0x15) +#define SET_LINE_CODING (0x20) +#define GET_LINE_CODING (0x21) +#define SET_CONTROL_LINE_STATE (0x22) +#define SEND_BREAK (0x23) +#define SET_RINGER_PARAMS (0x30) +#define GET_RINGER_PARAMS (0x31) +#define SET_OPERATION_PARAM (0x32) +#define GET_OPERATION_PARAM (0x33) +#define SET_LINE_PARAMS (0x34) +#define GET_LINE_PARAMS (0x35) +#define DIAL_DIGITS (0x36) +#define SET_UNIT_PARAMETER (0x37) +#define GET_UNIT_PARAMETER (0x38) +#define CLEAR_UNIT_PARAMETER (0x39) +#define GET_PROFILE (0x3A) +#define SET_ETHERNET_MULTICAST_FILTERS (0x40) +#define SET_ETHERNET_POW_PATTER_FILTER (0x41) +#define GET_ETHERNET_POW_PATTER_FILTER (0x42) +#define SET_ETHERNET_PACKET_FILTER (0x43) +#define GET_ETHERNET_STATISTIC (0x44) +#define SET_ATM_DATA_FORMAT (0x50) +#define GET_ATM_DEVICE_STATISTICS (0x51) +#define SET_ATM_DEFAULT_VC (0x52) +#define GET_ATM_VC_STATISTICS (0x53) +#define MDLM_SPECIFIC_REQUESTS_MASK (0x7F) + +/* Class Specific Notification Codes */ +#define NETWORK_CONNECTION_NOTIF (0x00) +#define RESPONSE_AVAIL_NOTIF (0x01) +#define AUX_JACK_HOOK_STATE_NOTIF (0x08) +#define RING_DETECT_NOTIF (0x09) +#define SERIAL_STATE_NOTIF (0x20) +#define CALL_STATE_CHANGE_NOTIF (0x28) +#define LINE_STATE_CHANGE_NOTIF (0x29) +#define CONNECTION_SPEED_CHANGE_NOTIF (0x2A) +#define MDLM_SPECIFIC_NOTIF_MASK (0x5F) + +/* Events to the Application */ /* 0 to 4 are reserved for class events */ +#define USB_APP_CDC_CARRIER_DEACTIVATED (0x21) +#define USB_APP_CDC_CARRIER_ACTIVATED (0x22) + +/* other macros */ +#define NOTIF_PACKET_SIZE (0x08) +#define NOTIF_REQUEST_TYPE (0xA1) + +/* macros for queuing */ +#define MAX_QUEUE_ELEMS (4) + +#if CIC_NOTIF_ELEM_SUPPORT +#define CIC_SEND_ENDPOINT CIC_NOTIF_ENDPOINT +#endif + +#if DIC_ISOCHRONOUS_SETTING + #define DIC_SEND_ENDPOINT DIC_ISO_IN_ENDPOINT + #define DIC_RECV_ENDPOINT DIC_ISO_OUT_ENDPOINT +#else + #define DIC_SEND_ENDPOINT DIC_BULK_IN_ENDPOINT + #define DIC_RECV_ENDPOINT DIC_BULK_OUT_ENDPOINT +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ +#ifndef COMPOSITE_DEV +typedef struct _app_data_struct +{ + uint_8_ptr data_ptr; /* pointer to buffer */ + USB_PACKET_SIZE data_size; /* buffer size of endpoint */ +}APP_DATA_STRUCT; +#endif + +/* structure to hold a request in the endpoint queue */ +typedef struct _usb_class_cdc_queue +{ + uint_8 controller_ID; /* Controller ID */ + uint_8 channel; /* Endpoint Number */ + APP_DATA_STRUCT app_data; /* Application Data Structure */ +}USB_CLASS_CDC_QUEUE, *PTR_USB_CLASS_CDC_QUEUE; + +/* USB class cdc endpoint data */ +typedef struct _usb_class_cdc_endpoint +{ + uint_8 endpoint; /* endpoint num */ + uint_8 type; /* type of endpoint (interrupt, bulk or isochronous) */ + uint_8 bin_consumer;/* the num of queued elements */ + uint_8 bin_producer;/* the num of de-queued elements */ + USB_CLASS_CDC_QUEUE queue[MAX_QUEUE_ELEMS]; /* queue data */ +}USB_CLASS_CDC_ENDPOINT; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Class_CDC_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK cdc_class_callback, /* [IN] CDC Class Callback */ + USB_REQ_FUNC vendor_req_callback, /* [IN] Vendor Request Callback */ + USB_CLASS_CALLBACK pstn_callback, /* [IN] PSTN Callback */ + uint_8 bVregEn /* Enables or disables internal regulator */ +); + +#ifdef COMPOSITE_DEV +extern uint_8 USB_CDC_Other_Requests(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +#endif + +extern uint_8 USB_Class_CDC_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Class_CDC_Send_Data ( + uint_8 controller_ID, + uint_8 ep_num, + uint_8_ptr buff_ptr, + USB_PACKET_SIZE size +); + +#if CIC_NOTIF_ELEM_SUPPORT +#define USB_Class_CDC_Interface_CIC_Send_Data(a,b,c) \ + USB_Class_CDC_Send_Data(a,CIC_SEND_ENDPOINT,b,c) +#endif + +#define USB_Class_CDC_Interface_DIC_Send_Data(a,b,c) \ + USB_Class_CDC_Send_Data(a,DIC_SEND_ENDPOINT,b,c) +#define USB_Class_CDC_Interface_DIC_Recv_Data(a,b,c) \ + _usb_device_recv_data(a,DIC_RECV_ENDPOINT,b,c) +#define USB_Class_CDC_Interface_DIC_Get_Send_Buffer(a,b,c) \ + _usb_device_get_send_buffer(a,DIC_SEND_ENDPOINT,b,c) + +#define USB_Class_CDC_Periodic_Task USB_Class_Periodic_Task + +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.c new file mode 100644 index 0000000..00bd791 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.c @@ -0,0 +1,409 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc_pstn.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB CDC_PSTN Sub Class implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "usb_cdc_pstn.h" /* USB CDC PSTN Sub Class Header File */ + + /***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/***************************************************************************** + * Global Functions Prototypes + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ +/* PSTN subclass callback pointer */ +static USB_CLASS_CALLBACK g_pstn_callback = NULL; +/* data terminal equipment present or not */ +static boolean g_dte_present = FALSE; +static uint_8 g_dte_status = 0; /* Status of DATA TERMINAL EQUIPMENT */ +static uint_16 g_break_duration = 0; /* Length of time in milliseconds of the + break signal */ +static uint_8 g_current_interface = 0; +static UART_BITMAP g_uart_bitmap; + +#if CIC_NOTIF_ELEM_SUPPORT +static uint_8 g_serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE] = +{ + NOTIF_REQUEST_TYPE,SERIAL_STATE_NOTIF, + 0x00,0x00,/*wValue*/ + 0x00,0x00,/*interface - modifies*/ + UART_BITMAP_SIZE,0x00,/* wlength*/ + 0x00,0x00 /*data initialized - modifies*/ +};/*uart bitmap*/ +#endif + /***************************************************************************** + * Local Functions + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Pstn_Init + * + * @brief The function initializes the PSTN Module + * + * @param controller_ID : Controller ID + * @param callback : PSTN Callback + * + * @return error + * USB_OK : Always + ****************************************************************************** + * PSTN Sub Class Initialization routine + *****************************************************************************/ +uint_8 USB_Class_CDC_Pstn_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK callback /* [IN] PSTN Callback */ +) +{ + uint_8 error = USB_OK; + UNUSED (controller_ID) + + /* save input parameters */ + g_pstn_callback = callback; + return error; +} +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Get_Line_Coding + * + * @brief This function is called in response to GetLineCoding request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data to be send + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE: When request for + * invalid Interface is presented + ****************************************************************************** + * Calls application to receive Line Coding Information + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Get_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data to be send */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + UNUSED (size) + g_current_interface = (uint_8)setup_packet->index ; + status = USB_Desc_Get_Line_Coding(controller_ID, g_current_interface, + data); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Line_Coding + * + * @brief This function is called in response to SetLineCoding request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Calls Applciation to update Line Coding Information + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + UNUSED(data) + + *size = 0; + + g_current_interface = (uint_8)setup_packet->index ; + status = USB_Desc_Set_Line_Coding(controller_ID, g_current_interface, + (uint_8_ptr *)&setup_packet); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Ctrl_Line_State + * + * @brief This function is called in response to Set Control Line State + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : Always + ****************************************************************************** + * Updates Control Line State + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Ctrl_Line_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + UNUSED(data) + *size = 0; + + g_dte_status = (uint_8)setup_packet->value ; + g_uart_bitmap._byte = 0x00; /* initialize */ + /* activate/deactivate Tx carrier */ + g_uart_bitmap.Bitmap_Uart.bTxCarrier = (g_dte_status & + CARRIER_ACTIVATION_CHECK) ? 1 : 0 ; + /* activate carrier and DTE */ + g_uart_bitmap.Bitmap_Uart.bRxCarrier = (g_dte_status & + CARRIER_ACTIVATION_CHECK) ? 1 : 0 ; + + /* Indicates to DCE if DTE is present or not */ + g_dte_present = (boolean)((g_dte_status & DTE_PRESENCE_CHECK) ? + TRUE : FALSE); + UNUSED(g_dte_present); +#if CIC_NOTIF_ELEM_SUPPORT + /* Send Notification to Host - Parameter on Device side has changed */ + USB_Class_CDC_PSTN_Send_Serial_State(controller_ID); +#endif + if(g_pstn_callback != NULL) + { +#if 1 /* original implementation */ + if(g_dte_status & CARRIER_ACTIVATION_CHECK) + { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_ACTIVATED, + NULL); + } + else + { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_DEACTIVATED, + NULL); + } +#else /* contribution from Joe Serdenkovski, see https://community.freescale.com/message/605537?et=watches.email.thread# */ + if(g_dte_status & CARRIER_ACTIVATION_CHECK) + { + if (g_dte_present) { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_ACTIVATED,NULL); + } else { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_DEACTIVATED,NULL); + } + } +#endif + } + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Send_Break + * + * @brief This function is called in response to Set Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : Always + ****************************************************************************** + * Updates Break Duration Information from Host + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Send_Break ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + UNUSED (controller_ID) + UNUSED (data) + *size = 0; + + g_break_duration = setup_packet->value; + UNUSED(g_break_duration); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Get_Comm_Feature + * + * @brief This function is called in response to GetCommFeature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data to be send + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Returns the status of the get comm feature request + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Get_Comm_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data to send */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ uint_8 status; + + status = USB_OK; + *size = COMM_FEATURE_DATA_SIZE; + g_current_interface = (uint_8)setup_packet->index ; + if(setup_packet->value == ABSTRACT_STATE_FEATURE) + { + status = USB_Desc_Get_Abstract_State(controller_ID, + g_current_interface, data); + } + else if(setup_packet->value == COUNTRY_SETTING_FEATURE) + { + status = USB_Desc_Get_Country_Setting(controller_ID, + g_current_interface, data); + } + else + { + *size = 0; /* for Reserved/Invalid Feature Selector Value */ + } + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Comm_Feature + * + * @brief This function is called in response to SetCommFeature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Sets the comm feature specified by Host + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Comm_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + status = USB_OK; + *size = COMM_FEATURE_DATA_SIZE; + g_current_interface = (uint_8)setup_packet->index ; + if(setup_packet->value == ABSTRACT_STATE_FEATURE) + { + status = USB_Desc_Set_Abstract_State(controller_ID, + g_current_interface, data); + } + else if(setup_packet->value == COUNTRY_SETTING_FEATURE) + { + status = USB_Desc_Set_Country_Setting(controller_ID, + g_current_interface, data); + } + else + { + *size = 0; /* for Reserved/Invalid Feature Selector Value */ + } + return status; +} + +#if CIC_NOTIF_ELEM_SUPPORT +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Send_Serial_State + * + * @brief This function is called to send serial state notification + * + * @param controller_ID : Controller ID + * + * @return NONE + ****************************************************************************** + * Returns the Serial State + *****************************************************************************/ +void USB_Class_CDC_PSTN_Send_Serial_State ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + /* update array for current interface */ + g_serial_state_buf[4] = g_current_interface; + /* Lower byte of UART BITMAP */ + g_serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE-2] = + g_uart_bitmap._byte; + (void)USB_Class_CDC_Interface_CIC_Send_Data(controller_ID, + g_serial_state_buf, (NOTIF_PACKET_SIZE + UART_BITMAP_SIZE)); +} +#endif + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.h new file mode 100644 index 0000000..8c363d7 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_cdc_pstn.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc_pstn.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB CDC_PSTN Sub Class API header function + * + *****************************************************************************/ + +#ifndef _USB_CDC_PSTN_H +#define _USB_CDC_PSTN_H + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "usb_cdc.h" /* USB CDC Class Header File */ +/****************************************************************************** + * Constants - None + *****************************************************************************/ +#ifdef __MCF52xxx_H__ +#pragma reverse_bitfields on +#endif +typedef struct _BITMAP_UART +{ + /*lint -save -e46 field type should be _Bool, unsigned int or signed int */ + uint_8 bRxCarrier : 1; /* Receive Carrier Activation Flag */ + uint_8 bTxCarrier : 1; /* Transmit Carrier Activation Flag */ + uint_8 bBreak : 1; /* Break Flag */ + uint_8 bRingSignal : 1; /* Ring Signal Flag */ + uint_8 bFraming : 1; /* Frame Flag */ + uint_8 bParity : 1; /* Parity Flag */ + uint_8 bOverRun : 1; /* OverRun Flag */ + uint_8 reserved1 : 1; /* Reserved */ + /*lint -restore */ +}BITMAP_UART; +#ifdef __MCF52xxx_H__ +#pragma reverse_bitfields off +#endif + + +typedef union _UART_BITMAP +{ + uint_8 _byte; + BITMAP_UART Bitmap_Uart; +}UART_BITMAP; /* UART STATE BITMAP */ + + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define UART_BITMAP_SIZE (0x02) +#define ABSTRACT_STATE_FEATURE (0x01) +#define COUNTRY_SETTING_FEATURE (0x02) +#define CARRIER_ACTIVATION_CHECK (0x02) +#define DTE_PRESENCE_CHECK (0x01) + +extern uint_8 USB_Class_CDC_Pstn_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK callback +); + +extern uint_8 USB_Class_CDC_PSTN_Get_Line_Coding ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Line_Coding ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Ctrl_Line_State ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Send_Break ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Get_Comm_Feature ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Comm_Feature ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +#if CIC_NOTIF_ELEM_SUPPORT +extern void USB_Class_CDC_PSTN_Send_Serial_State (uint_8 controller_ID); +#endif +#endif + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.c new file mode 100644 index 0000000..7f79e45 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.c @@ -0,0 +1,493 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_class.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains USB stack Class module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_class.h" /* USB class Header File */ +#include "usb_devapi.h" /* USB device Header file */ +#include "usb_framework.h" /* USB framework module header file */ +#include "hidef.h" /* for EnableInterrupts macro */ + +#if 0 /* << EST */ +#if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) +#include "exceptions.h" +#endif +#else +/* device is Kinetis K20D50 << EST */ +#endif +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + /* Class callback pointer */ +static USB_CLASS_CALLBACK g_class_callback = NULL; +/* save the device state before device goes to suspend state */ +static uint_8 g_device_state_before_suspend; +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +void USB_Suspend_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Resume_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Stall_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Sof_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Reset_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Error_Service (PTR_USB_DEV_EVENT_STRUCT event ); + +/***************************************************************************** + * Local Variables + *****************************************************************************/ + + /***************************************************************************** + * Local Functions - None + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K20D50 << EST */ +#endif +/**************************************************************************//*! + * + * @name USB_Suspend_Service + * + * @brief The function is called when host suspends the USB port + * + * @param event : Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Sets the device state as USB_STATE_SUSPEND + *****************************************************************************/ +void USB_Suspend_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* Get the status of the device before suspend, so that on resume we + can get back to the same state */ + (void)_usb_device_get_status(&(event->controller_ID), + USB_STATUS_DEVICE_STATE, &g_device_state_before_suspend); + /* Set the device state in the Device Layer to SUSPEND */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + USB_STATE_SUSPEND); + + /* let the application know that bus suspend has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_SUSPEND, NULL); + + return; +} + +/**************************************************************************//*! + * + * @name USB_Resume_Service + * + * @brief The function is called when host resumes the USB port + * + * @param event : Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Restore the state of the device before suspend + *****************************************************************************/ +void USB_Resume_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_8 device_state; + (void)_usb_device_get_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + &device_state); + if(device_state == USB_STATE_SUSPEND) + { + /* + Set the device state in the Device Layer to the state + before suspend + */ + (void)_usb_device_set_status(&(event->controller_ID), + USB_STATUS_DEVICE_STATE, g_device_state_before_suspend); + } + + /* let the application know that bus resume has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_RESUME, NULL); + + return; +} + +/**************************************************************************//*! + * + * @name USB_Stall_Service + * + * @brief The function is called when endpoint is stalled + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * This function sends STALL Packet for the endpoint to be stalled. Also, sets + * the status of Endpoint as STALLED + *****************************************************************************/ +void USB_Stall_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + if(event->ep_num == CONTROL_ENDPOINT) + { + /* Update the Endpoint Status in the Device Layer to Idle */ + (void)_usb_device_set_status(&(event->controller_ID), + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (event->direction << USB_COMPONENT_DIRECTION_SHIFT)), + (uint_16)USB_STATUS_IDLE); + } + return; +} + +/**************************************************************************//*! + * + * @name USB_Sof_Service + * + * @brief The function is called when SOF flag is set (from ISR) + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * This function is called when SOF token is received by controller. Updates + * SOF Count status. + *****************************************************************************/ +void USB_Sof_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_16 sof_count; + + /* update SOF */ + sof_count = event->buffer_ptr[0]; + sof_count <<= SOF_HIGH_BYTE_SHIFT; + sof_count |= event->buffer_ptr[1]; + + /* write SOF to status */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_SOF_COUNT, + (uint_8)sof_count); + return; +} +/**************************************************************************//*! + * + * @name USB_Reset_Service + * + * @brief The function is called upon a bus reset event. + Initializes the control endpoint. + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Reset Callback function. This function re-initializes CONTROL Endpoint + *****************************************************************************/ +void USB_Reset_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + + USB_EP_STRUCT ep_struct; + uint_8 err; + + /* Initialize the endpoint 0 in both directions */ + ep_struct.direction = USB_SEND; + ep_struct.ep_num = CONTROL_ENDPOINT; + ep_struct.size = CONTROL_MAX_PACKET_SIZE; + ep_struct.type = USB_CONTROL_PIPE; + + /* Deinit Endpoint in case its already initialized */ + err = _usb_device_deinit_endpoint(&(event->controller_ID), + ep_struct.ep_num, ep_struct.direction); + /* now initialize the endpoint */ + err = _usb_device_init_endpoint(&(event->controller_ID), + ep_struct.ep_num, (uint_16)ep_struct.size, ep_struct.direction, ep_struct.type, TRUE); + + ep_struct.direction = USB_RECV; + /* Deinit Endpoint in case its already initialized */ + (void)_usb_device_deinit_endpoint(&(event->controller_ID), + ep_struct.ep_num, ep_struct.direction); + /* now initialize the endpoint */ + (void)_usb_device_init_endpoint(&(event->controller_ID), + ep_struct.ep_num, (uint_16)ep_struct.size, ep_struct.direction, ep_struct.type, TRUE); + + /* set the default device state */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + USB_STATE_DEFAULT); + + /* set the default device state */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE, + SELF_POWERED >> SELF_POWER_BIT_SHIFT); + + /* set the EndPoint Status as Idle in the device layer */ + (void)_usb_device_set_status(&(event->controller_ID), + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (USB_SEND << USB_COMPONENT_DIRECTION_SHIFT)), + USB_STATUS_IDLE); + /* let the application know that bus reset has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_RESET, NULL); + + UNUSED(err); + return; +} + +/**************************************************************************//*! + * + * @name USB_Error_Service + * + * @brief The function is called when an error has been detected + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Calls application with the error code received from the lower layer + *****************************************************************************/ +void USB_Error_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* notify the application of the error */ + g_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + return; +} + + +/**************************************************************************//*! + * + * @name USB_Class_Init + * + * @brief The function initializes the Class Module + * + * @param controller_ID : Controller ID + * @param class_callback : Class callback + * @param other_req_callback : Other Requests Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Initializes USB Class Module + *****************************************************************************/ +uint_8 USB_Class_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK class_callback, /* [IN] Class Callback */ + USB_REQ_FUNC other_req_callback /* [IN] Other Requests Callback */ +) +{ + uint_8 status = USB_Framework_Init(controller_ID,class_callback, + other_req_callback); + + /* save callback address */ + g_class_callback = class_callback; + + if(status == USB_OK) + { + /* Register all the services here */ + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_BUS_RESET, USB_Reset_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_SOF,USB_Sof_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_SLEEP,USB_Suspend_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_RESUME,USB_Resume_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_STALL,USB_Stall_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_ERROR,USB_Error_Service); + + /* set the device state as powered */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE,USB_STATE_POWERED); + g_device_state_before_suspend = USB_STATE_POWERED; + } + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_DeInit + * + * @brief The function De-initializes the Class Module + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * De-initializes USB Class Module + *****************************************************************************/ +uint_8 USB_Class_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 status = USB_OK; + /* Free class_callback */ + g_class_callback = NULL; + + /* Unegister all the services here */ + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_BUS_RESET); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_SOF); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_SLEEP); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_RESUME); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_STALL); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_ERROR); + + if(status == USB_OK) + /* Call Framework deinit function */ + status = USB_Framework_DeInit(controller_ID); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_Initiate_Resume + * + * @brief The function initiates resume procedure + * + * @param controller_ID : Controller ID + * + * @return device_state + ******************************************************************************/ +uint_8 USB_Class_Initiate_Resume( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 device_state, state; + + (void)_usb_device_get_status(&controller_ID, USB_STATUS_DEVICE_STATE, + &device_state); + (void)_usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &state); + if((device_state == USB_STATE_SUSPEND) && + (state & REMOTE_WAKEUP_STATUS_MASK ) && + (USB_Frame_Remote_Wakeup(controller_ID) == TRUE)) + { + DisableInterrupts; +#if 0 + #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) + usb_int_dis(); + #endif +#else /* << EST */ + /* device is Kinetis K20D50 << EST */ +#endif + /* Resume the bus */ + _usb_device_assert_resume(&controller_ID); + + device_state = USB_STATE_CONFIG; + /* Set the device state in the Device Layer to DEFAULT */ + (void)_usb_device_set_status(&controller_ID, USB_STATUS_DEVICE_STATE, + USB_STATE_CONFIG); + EnableInterrupts; + #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) + usb_int_en(); + #endif + } + return device_state; +} + +/**************************************************************************//*! + * + * @name USB_Class_Send_Data + * + * @brief The function calls the device to send data upon receiving an IN token + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param buff_ptr : Buffer to send + * @param size : Length of transfer + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Used by Application to send Data on USB Bus if not suspended + *****************************************************************************/ +uint_8 USB_Class_Send_Data ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8_ptr buff_ptr, /* [IN] Buffer to send */ + USB_PACKET_SIZE size /* [IN] Length of the transfer */ +) +{ + + uint_8 status = USB_OK; + uint_8 device_state; + + device_state = USB_Class_Initiate_Resume(controller_ID); + + if(device_state != USB_STATE_SUSPEND) + { /* if not suspended */ + status = _usb_device_send_data(&controller_ID, ep_num, buff_ptr, size); + } + + return status; + } + +/**************************************************************************//*! + * + * @name USB_Class_Periodic_Task + * + * @brief The function calls for periodic tasks + * + * @param None + * + * @return None + ****************************************************************************** + * Called to check for any pending requests + *****************************************************************************/ +void USB_Class_Periodic_Task (void) +{ +#ifdef DELAYED_PROCESSING + USB_Framework_Periodic_Task(); +#endif +} + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.h new file mode 100644 index 0000000..6d377ab --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_class.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_class.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack class layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_CLASS_H +#define _USB_CLASS_H + + +/*#define DELAYED_PROCESSING 1 This define is used to delay the control + processing and not have it executed as part + of the interrupt routine */ +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define SOF_HIGH_BYTE_SHIFT (8) +#define GET_STATUS_DEVICE_MASK (0x0003) +#ifdef OTG_BUILD +#define GET_STATUS_OTG_MASK (0x0001) +#endif +#define REMOTE_WAKEUP_STATUS_MASK (0x0002) +#define BUS_POWERED (0x80) +#define SELF_POWERED (0x40) +#define SELF_POWER_BIT_SHIFT (6) + +/* Events to the Application */ +#define USB_APP_BUS_RESET (0) +#define USB_APP_CONFIG_CHANGED (1) +#define USB_APP_ENUM_COMPLETE (2) +#define USB_APP_SEND_COMPLETE (3) +#define USB_APP_DATA_RECEIVED (4) +#define USB_APP_ERROR (5) +#define USB_APP_GET_DATA_BUFF (6) +#define USB_APP_EP_STALLED (7) +#define USB_APP_EP_UNSTALLED (8) +#define USB_APP_GET_TRANSFER_SIZE (9) +#define USB_APP_BUS_SUSPEND (0x0A) +#define USB_APP_BUS_RESUME (0x0B) + +/* max packet size for the control endpoint */ + +/* USB Specs define CONTROL_MAX_PACKET_SIZE for High Speed device as only 64, + whereas for FS its allowed to be 8, 16, 32 or 64 */ + +#if HIGH_SPEED_DEVICE +#define CONTROL_MAX_PACKET_SIZE (64) /* max supported value is 64*/ +#else +#define CONTROL_MAX_PACKET_SIZE (16) /* max supported value is 16*/ +#endif + +/* identification values and masks to identify request types */ +#define USB_REQUEST_CLASS_MASK (0x60) +#define USB_REQUEST_CLASS_STRD (0x00) +#define USB_REQUEST_CLASS_CLASS (0x20) +#define USB_REQUEST_CLASS_VENDOR (0x40) + +/****************************************************************************** + * Types + *****************************************************************************/ +/* eight byte usb setup packet structure */ +typedef struct _USB_SETUP_STRUCT { + uint_8 request_type; /* bmRequestType */ + uint_8 request; /* Request code */ + uint_16 value; /* wValue */ + uint_16 index; /* wIndex */ + uint_16 length; /* Length of the data */ +} USB_SETUP_STRUCT; + +/* callback function pointer structure for Application to handle events */ +typedef void(_CODE_PTR_ USB_CLASS_CALLBACK)(uint_8, uint_8, void*); + +/* callback function pointer structure to handle USB framework request */ +typedef uint_8 (_CODE_PTR_ USB_REQ_FUNC)(uint_8, USB_SETUP_STRUCT *, + uint_8_ptr*, + USB_PACKET_SIZE*); + +/*callback function pointer structure for application to provide class params*/ +typedef uint_8 (_CODE_PTR_ USB_CLASS_SPECIFIC_HANDLER_FUNC)( + uint_8, + uint_16, + uint_16, // Application needs to know which Interface is being communicated with + uint_8_ptr*, + USB_PACKET_SIZE*); + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Class_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK class_callback, + USB_REQ_FUNC other_req_callback +); + +extern uint_8 USB_Class_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Class_Initiate_Resume( + uint_8 controller_ID +); + +extern uint_8 USB_Class_Send_Data ( + uint_8 controller_ID, + uint_8 ep_num, + uint_8_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern void USB_Class_Periodic_Task(void); + +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.c new file mode 100644 index 0000000..8a63c67 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.c @@ -0,0 +1,2954 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2012 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dci_kinetis.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains Kinetis USB stack controller layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include +#include "usb_dciapi.h" /* USB DCI API Header File */ +#include "usb_devapi.h" /* USB Device API Header File */ +#include "usb_dci_kinetis.h" /* USB DCI Header File */ +#include "usb_bdt_kinetis.h" /* USB BDT Structure Header File */ +#include "wdt_kinetis.h" +#include "usb_class.h" + +/***************************************************************************** + * Constant and Macro's - None + *****************************************************************************/ +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef USE_FEEDBACK_ENDPOINT + extern uint_32 feedback_data; + extern uint_32 gNrSamples; +#endif + +/* location for BDT Table and buff */ +#if (defined(__CWCC__)||defined(__GNUC__)) + __attribute__((__aligned__(512))) +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma data_alignment = 512 +#endif + +#if !HIGH_SPEED_DEVICE + #if defined __CC_ARM + __align(512) uint_8 g_Mem[BYTES_1024]; + #else +#if 0 + static uint_8 g_Mem[BYTES_1024]; +#else + uint_8 g_Mem[BYTES_1024]; +#endif + #endif + /* Pointer to BDT Map Structure */ + BDTMAP *g_bdtmap = NULL; + /* per endpoint per direction bdt index structure */ + static BDT_ELEM g_bdt_elem[MAX_BDT_INDEX >> 1]; +#endif +/* stores Controller ID */ +static uint_8 g_dci_controller_Id = 0; +#if HIGH_SPEED_DEVICE +static uint_8 g_dci_address_state = 0; +#endif /* HIGH_SPEED_DEVICE */ + +#if !HIGH_SPEED_DEVICE +/* Start BDT buffer Address */ +static uint_32 g_bdt_address; +#endif /* HIGH_SPEED_DEVICE */ +/* Transfer direction */ +static uint_8 g_trf_direction = USB_TRF_UNKNOWN; + + +// HIGH_SPEED_DEVICE +#if HIGH_SPEED_DEVICE + #define MAX_DTDS_PER_EP 5 // maximum number of transfer descriptors + #define DTD_FREE 0 + #define DTD_BUSY 1 + #define MAX_ENDPOINT_NUMBER 4 + + // QH structures are 64-byte aligned + #define TOTAL_QHD_SIZE (SIZE_OF_QHD * (MAX_ENDPOINT_NUMBER * 2)) + // TD structures are 64-byte aligned + #define TOTAL_QTD_SIZE ((SIZE_OF_DTD0) * (MAX_ENDPOINT_NUMBER * 2) * MAX_DTDS_PER_EP) + + #ifdef __CWCC__ + #pragma define_section usb_dqh ".usb_dqh" RW + __declspec(usb_dqh) uint_8 g_usbd_qh_buf[TOTAL_QHD_SIZE]; // 512 + #pragma define_section usb_dtd ".usb_dtd" RW + __declspec(usb_dtd) uint_8 g_usbd_td_buf[TOTAL_QTD_SIZE]; // 1280 + #else + #pragma data_alignment=(0x1000) + uint_8 g_usbd_qh_buf[TOTAL_QHD_SIZE]; // 512 + #pragma data_alignment=(0x800) + uint_8 g_usbd_td_buf[TOTAL_QTD_SIZE]; // 1280 + #endif + + + /* flag status for td */ + static struct _td_status + { + uint_8 status; // DTD_BUSY or DTD_FREE + unsigned int total_bytes; // Original total bytes to transfer (not used by EP0) + volatile struct dtd_setup_t *phys_td; // Pointer to physical TD (not used by EP0) + } g_usbd_td_flag[MAX_ENDPOINT_NUMBER * 2][MAX_DTDS_PER_EP]; + static struct dtd_setup_t *g_usbd_qh_tail[MAX_ENDPOINT_NUMBER * 2]; +#endif // HIGH_SPEED_DEVICE + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +static void USB_Bus_Reset_Handler(void); +#if !HIGH_SPEED_DEVICE +static uint_8 USB_DCI_Get_BDT_Index(uint_8 ep_num, + uint_8 direction, + boolean odd); +static uint_8 USB_DCI_Validate_Param(uint_8 ep_num, + uint_8 direction, + boolean odd); +#ifdef LONG_SEND_TRANSACTION +static void USB_DCI_Prepare_Send_Data(P_BUFF_DSC buffer_dsc, + P_BDT_ELEM bdt_elem); +#endif /* LONG_SEND_TRANSACTION */ +static void USB_Bus_Token_Cpl_Handler(uint_8 stat, + USB_DEV_EVENT_STRUCT* event); +#endif /* HIGH_SPEED_DEVICE */ + +// HIGH_SPEED_DEVICE +#if HIGH_SPEED_DEVICE +static uint_8 K70_ULPI_SetDeviceMode(uint_8 controller_ID); +static void usbd_ep_qh_init(uint_8 controller_ID, + unsigned char endpt_number, unsigned char direction, + unsigned int max_pkt_len, + unsigned int zlt, unsigned char mult, uint_32 next_dtd); +static void usbd_setup_qhead(struct dqh_t *qhead); +static void usbd_setup_td(struct dtd_t *td); +static unsigned int usbd_get_dqh(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction); +static void usbd_ep_setup(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned char ep_type); +static void usbd_ep_complete_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_setup_packet_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_read_setup_packet(uint_8 controller_ID, unsigned char *setup_packet); +static void usbd_port_change( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_ep0_complete(USB_DEV_EVENT_STRUCT* event); +static void usbd_dtd_complete(USB_DEV_EVENT_STRUCT* event); +static usb_status_t usbd_receive_data_ep0out(uint_8 controller_ID, unsigned int ep0_data_buffer, unsigned int sz); +static usb_status_t usbd_receive_data_epxout(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz); +static void usbd_add_td(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td); +static void usbd_prime_ep(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td); +static usb_status_t usbd_send_data_epxin(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz); +static usb_status_t usbd_send_data_ep0in(uint_8 controller_ID, + unsigned int ep0_data_buffer, unsigned int sz, + unsigned char zlt_enable); + +#endif +#ifdef USB_LOWPOWERMODE + static void Enter_StopMode(STOP_MODE stop_mode); +#endif +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_Bus_Reset_Handler + * + * @brief The function handles Bus Reset Interrupt + * + * @param None + * + * @return None + * + ****************************************************************************** + * This functions is called when USB Bus Reset event is received on USB Bus. + * This function clears all the errors conditions and reinit Global data + * structures. Also resets USB device controller. + *****************************************************************************/ +static void USB_Bus_Reset_Handler (void) +{ +#if !HIGH_SPEED_DEVICE + USB0_ERRSTAT = ERR_STAT_CLEAR_ALL; /* clear USB error flag */ + USB0_CTL |= USB_CTL_ODDRST_MASK; /* Reset to Even buffer */ + USB0_ADDR = 0; /* reset to default address */ + /* Select System Clock and Disable Weak Pull Downs */ + USB0_USBCTRL = 0x00; + + /* Clear bdt elem structure */ + Clear_Mem((uint_8_ptr)(g_bdt_elem), + (sizeof(BDT_ELEM) * (MAX_BDT_INDEX >> 1)), + (uint_8)UNINITIALISED_VAL); + + /* Clear Memory for BDT and buffer Data */ + Clear_Mem((uint_8_ptr)g_bdtmap,(uint_32) BYTES_1024, (uint_8)0); + + /* Initialize BDT buffer address */ + g_bdt_address = ((uint_32)g_bdtmap + BYTES_512); + + g_trf_direction = USB_TRF_UNKNOWN; + + USB0_CTL &= ~USB_CTL_ODDRST_MASK; + USB0_USBTRC0 |= 0x40; /* attach CFv1 core to USB bus */ + + USB0_ERREN = ERR_ENB_ENABLE_ALL; /* Enable All Error Interrupts */ + USB0_INTEN = INTENB_BUS_RESET_VAL; /* Enable All Interrupts except RESUME */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + +#else + uint_32 reg; + + //Clear the device address + USBHS_DEVICEADDR &= ~USBHS_DEVICEADDR_USBADR_MASK; + + // 1. Clear all setup token semaphores + reg = USBHS_EPSETUPSR; + USBHS_EPSETUPSR = reg; + + // 2. Clear all the endpoint complete status bits + reg = USBHS_EPCOMPLETE; + USBHS_EPCOMPLETE = reg; + + // 3. Cancel all primed status + while(USBHS_EPPRIME); + USBHS_EPFLUSH = 0xffffffff; + + // 4. If reset bit is not cleared at this point force reset device + if(!(USBHS_PORTSC1 & USBHS_PORTSC1_PR_MASK)){ + USBHS_USBCMD |= USBHS_USBCMD_RST_MASK; + } + + // 5. Free(reset) all allocated dTDs + memset(g_usbd_td_buf, 0, TOTAL_QTD_SIZE); + memset(g_usbd_td_flag, + 0, + MAX_ENDPOINT_NUMBER * 2 * MAX_DTDS_PER_EP * sizeof(g_usbd_td_flag)/sizeof(*g_usbd_td_flag) + ); + + g_trf_direction = USB_TRF_UNKNOWN; + UNUSED(g_trf_direction); +#endif +} + +#if !HIGH_SPEED_DEVICE +/**************************************************************************//*! + * + * @name USB_DCI_Get_BDT_Index + * + * @brief The function maps endpoint number and direction to bdt index + * + * @param ep_num : Endpoint Number + * @param direction: Endpoint direction + * @param odd : Odd or even buffer + * + * @return bdt index : Mapped bdt index + * INVALID_BDT_INDEX : In case of error + * + ****************************************************************************** + * This function returns BDT Index from Endpoint number, direction, + * odd/even buffer + *****************************************************************************/ +static uint_8 USB_DCI_Get_BDT_Index ( + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8 direction, /* [IN] Endpoint direction */ + boolean odd /* [IN] Odd or even buffer */ +) +{ + uint_8 bdt_index = INVALID_BDT_INDEX; + + if(ep_num < MAX_SUPPORTED_ENDPOINTS) + { + /* per endpoint 4 bdt_index -- 2 for recv 2 for send */ + bdt_index=(uint_8)((ep_num * 4) + (uint_8)odd); + + if(direction == USB_SEND) + { + bdt_index += 2; + } + } + return bdt_index; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Validate_Param + * + * @brief The function validates endpoint number & direction parameters + * and returns bdt index. + * + * @param ep_num : Endpoint Number + * @param direction: Endpoint direction + * @param odd : odd or even buffer + * + * @return bdt index : mapped bdt index + * INVALID_BDT_INDEX : incase of error + * + ****************************************************************************** + * This function validates endpoint parameters and returns bdt index + *****************************************************************************/ +static uint_8 USB_DCI_Validate_Param ( + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8 direction, /* [IN] Endpoint direction */ + boolean odd /* [IN] Odd or even buffer */ +) +{ + /* Get bdt index mapped to endpoint number-direction and odd/even buffer */ + uint_8 bdt_index = USB_DCI_Get_BDT_Index(ep_num, direction, odd); + + if((bdt_index != INVALID_BDT_INDEX) && + (g_bdt_elem[TRANSFER_INDEX(bdt_index)].len == + (uint_16)UNINITIALISED_VAL)) + { + /* Incase length in bdt_elem is uninitialised return invalid index */ + bdt_index = INVALID_BDT_INDEX; + } + return bdt_index; +} +#endif /* HIGH_SPEED_DEVICE */ + +#ifdef LONG_SEND_TRANSACTION +#if !HIGH_SPEED_DEVICE +/**************************************************************************//*! + * + * @name USB_DCI_Prepare_Send_Data + * + * @brief The function sets up the BDT for Send + * + * @param buffer_dsc : Pointer to buffer descriptor element in USB_RAM + * @param bdt_elem : Pointer to per endpoint/direction structure + * + * @return None + * + ****************************************************************************** + * This functions configures Buffer Descriptor (Address and Count) + *****************************************************************************/ +static void USB_DCI_Prepare_Send_Data ( + P_BUFF_DSC buffer_dsc, /* [OUT] Pointer to buffer descriptor + element in USB_RAM */ + P_BDT_ELEM bdt_elem /* [IN] Pointer to per endpoint/direction + structure */ +) +{ + uint_8_ptr buff_ptr = bdt_elem->app_buffer + bdt_elem->curr_offset; + uint_16 current_count = 0; + + /* adjust size based on the input at the init endpoint */ + if((bdt_elem->app_len - bdt_elem->curr_offset) > bdt_elem->len) + { + /* If size of packet is greater than endpoint buffer size */ + current_count = bdt_elem->len; + } + else + { + /* If size of packet is smaller than endpoint buffer size */ + current_count = (uint_16)(bdt_elem->app_len - bdt_elem->curr_offset); + } + + buffer_dsc->cnt = SWAP16(current_count); + + buffer_dsc->addr = SWAP32((uint_32)buff_ptr); +} +#endif /* HIGH_SPEED_DEVICE */ +#endif /* LONG_SEND_TRANSACTION */ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_DCI_Init + * + * @brief The function initializes the Controller layer + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : Always + ****************************************************************************** + * Initializes the USB controller + *****************************************************************************/ +uint_8 USB_DCI_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ +#if !HIGH_SPEED_DEVICE +#if USB_USER_CONFIG_USE_STACK_INIT + /* Select System Clock and Disable Weak Pull Downs */ + USB0_USBCTRL = 0x00; +#endif + + /* save the controller_ID for future use */ + g_dci_controller_Id = controller_ID; + + /* Clear bdt elem structure */ + Clear_Mem((uint_8_ptr)(g_bdt_elem), + (sizeof(BDT_ELEM) * (MAX_BDT_INDEX >> 1)), + (uint_8)UNINITIALISED_VAL); + g_bdtmap = (BDTMAP *)((uint_32)g_Mem); + + /* Clear Memory for BDT and buffer Data */ + Clear_Mem((uint_8_ptr)g_bdtmap,(uint_32) BYTES_1024, (uint_8)0); + + #ifndef OTG_BUILD + #if 1 /* hardware bug workaround */ /* << EST: need to keep this workaround for FRDM-KL25Z */ + /* Hard Reset to the USB Module */ + USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + + /* loop till the Reset bit clears */ + while((USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK)) + { + }; + #if !USB_USER_CONFIG_USE_STACK_INIT + { + /* need to re-init USB, as the hard reset above has reset the whole module! */ + void USB0_Init(void); /* prototype */ + USB0_Init(); /* call Processor Expert Init_USB_OTG Init() */ + } + #endif + + #endif + #endif + + g_trf_direction = USB_TRF_UNKNOWN; + +#if USB_USER_CONFIG_USE_STACK_INIT + /* Asynchronous Resume Interrupt Enable */ + USB0_USBTRC0 |= 0x40; /* undocumented bit???? */ +#endif + if(bVregEn) + { + SIM_SOPT1 |= SIM_SOPT1_USBREGEN_MASK; // enable usb voltage regulator + } + else + { + SIM_SOPT1 &= ~SIM_SOPT1_USBREGEN_MASK; // disable usb voltage regulator + } + + /* Set the BDT Table address, Need to be on 512 byte boundary */ + /* D8 Bit is masked in BDT_PAGE_01 */ + USB0_BDTPAGE1 = (uint_8)(((uint_32)g_bdtmap >> 8)& 0xFE); + USB0_BDTPAGE2 = (uint_8)((uint_32)g_bdtmap >> 16); + USB0_BDTPAGE3 = (uint_8)((uint_32)g_bdtmap >> 24); + + /* Initialized BDT buffer address */ + g_bdt_address = ((uint_32)g_bdtmap + BYTES_512); + +#if USB_USER_CONFIG_USE_STACK_INIT + #ifndef OTG_BUILD + /* Pull Up configuration */ + USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK; + #endif +#endif + USB0_CTL = USB_CTL_USBENSOFEN_MASK; /* Enable USB module */ + USB0_ISTAT = INT_STAT_CLEAR_ALL; /* Clear USB interrupts*/ + + /* Remove suspend state */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + +#if USB_USER_CONFIG_USE_STACK_INIT + /* Enable USB RESET Interrupt */ + USB0_INTEN |= USB_INTEN_USBRSTEN_MASK; + + /* Enable USB Sleep Interrupt */ + USB0_INTEN |= USB_INTEN_SLEEPEN_MASK; + + USB0_OTGCTL = USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK; +#endif /* USB_USER_CONFIG_USE_STACK_INIT */ +#else // HIGH_SPEED_DEVICE + /* save the controller_ID for future use */ + g_dci_controller_Id = controller_ID; + memset(g_usbd_qh_buf, 0, TOTAL_QHD_SIZE); + memset(g_usbd_td_buf, 0, TOTAL_QTD_SIZE); + + // initialize module in device mode + uint_8 status; + status = K70_ULPI_SetDeviceMode(controller_ID); + if (status != USB_OK) + return status; + + // initialize endpoint 0 + usbd_ep_qh_init(controller_ID, EP0, IN, 64, 0, 0, 1); + usbd_ep_qh_init(controller_ID, EP0, OUT, 64, 0, 0, 1); + + // setup interrupts + USBHS_USBINTR = USBHS_USBINTR_UE_MASK // USB interrupt + | USBHS_USBINTR_UEE_MASK // USB error + | USBHS_USBINTR_PCE_MASK // Port change + | USBHS_USBINTR_URE_MASK // Reset enable + | USBHS_USBINTR_SRE_MASK // SOF received + | USBHS_USBINTR_SLE_MASK // suspend received + | USBHS_USBINTR_SEE_MASK; // System error + + // enable pullup on DP and initiate attach event + USBHS_USBCMD |= USBHS_USBCMD_RS_MASK; +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_DeInit + * + * @brief The function de-initializes the Controller layer + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : Always + ****************************************************************************** + * Initializes the USB controller + *****************************************************************************/ +uint_8 USB_DCI_DeInit(void) +{ +#if !HIGH_SPEED_DEVICE + +#ifdef MCU_MK70F12 +#if 0 /* hardware bug workaround */ + // Reset module + USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + + // Wait for reset to complete + while((USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK)); +#endif + +#else + /* Detach CFv1 core to USB bus*/ + USB0_USBTRC0 &= ~0x40; +#endif + + + /* Clear USB interrupts*/ + USB0_ISTAT = INT_STAT_CLEAR_ALL; + + /* Disable USB RESET Interrupt */ + USB0_INTEN &= ~USB_INTEN_USBRSTEN_MASK; + + /* Disable USB module */ + USB0_CTL &= ~USB_CTL_USBENSOFEN_MASK; + + USB0_OTGCTL &= ~(USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK); +#else // HIGH_SPEED_DEVICE + +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Init_EndPoint + * + * @brief The function initializes an endpoint + * + * @param controller_ID : Controller ID + * @param ep_ptr : Pointer to EndPoint Structures + * @param flag : Zero Termination + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_INIT_FAILED : When Error + ****************************************************************************** + * + * This function initializes an endpoint and the Bufffer Descriptor Table + * entry associated with it. Incase the input parameters are invalid it will + * return USBERR_EP_INIT_FAILED error. + * + *****************************************************************************/ +uint_8 USB_DCI_Init_EndPoint ( + uint_8 controller_ID,/* [IN] Controller ID */ + USB_EP_STRUCT_PTR ep_ptr, /* [IN] Pointer to Endpoint structure, + (endpoint number, + endpoint type, + endpoint direction, + max packet size) */ + boolean flag /* [IN] Zero Termination */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_8 bdtmap_index; + uint_8 bdtelem_index; + uint_8 ep_num = ep_ptr->ep_num; + uint_8 direction = ep_ptr->direction; + uint_32 ep_ctrl[2] = {EP_OUT, EP_IN}; + P_BUFF_DSC temp; + P_BDT_ELEM bdt_elem; + UNUSED(controller_ID); + + /* if the max packet size is greater than the max buffer size */ + if(ep_ptr->size > MAX_EP_BUFFER_SIZE) + { + ep_ptr->size = MAX_EP_BUFFER_SIZE; + } + + /* Get the bdt index correspoding to the endpoint */ + bdtmap_index = USB_DCI_Get_BDT_Index(ep_num, direction, + USB_RAM_EVEN_BUFFER); + bdtelem_index = (uint_8)TRANSFER_INDEX(bdtmap_index); + + /* + incase the bdtmap_index is invalid + or already initialised return with an error + */ + if((bdtmap_index == INVALID_BDT_INDEX) || + (g_bdt_elem[bdtelem_index].len != (uint_16)UNINITIALISED_VAL) || + (ep_ptr->type > USB_INTERRUPT_PIPE) || + (ep_ptr->direction > USB_SEND)) + { + return USBERR_EP_INIT_FAILED; + } + + bdt_elem = &g_bdt_elem[bdtelem_index]; + /* Reset Handler resets bdtmap_index to UNINITIALISED_VAL */ + if(bdt_elem->bdtmap_index == (uint_8)UNINITIALISED_VAL) + { + bdt_elem->bdtmap_index = 0; + } + + /* update bdt element structure */ + bdt_elem->len = (uint_16)ep_ptr->size; + bdt_elem->flag = flag; + /* preserving even/odd buffer bit */ + bdt_elem->bdtmap_index &= 0x01; + bdt_elem->bdtmap_index |= ((direction << 1) | (ep_num << 2)); + bdt_elem->addr = g_bdt_address; + bdt_elem->type = ep_ptr->type; + bdt_elem->direction = direction; + + temp = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + + /* Update BDTMAP for endpoint's EVEN Buffer */ + temp->cnt = SWAP16((uint_16)ep_ptr->size); + temp->addr = SWAP32(g_bdt_address); + temp->Stat._byte = (_CPU | _DATA0 | _DTS); + + /* Update BDTMAP for endpoint's ODD Buffer */ + temp = &g_bdtmap->ep_dsc[(uint8_t)((bdt_elem->bdtmap_index) ^ 1)]; + + temp->cnt = SWAP16((uint_16)ep_ptr->size); + temp->addr = SWAP32(g_bdt_address); + temp->Stat._byte = (_CPU | _DATA1 | _DTS); + + /* update the buffer address for the next endpoint */ + g_bdt_address += ep_ptr->size; + + if(direction == USB_RECV) + { + /* + For Recv Endpoints + Give SIE Control to DATA0 + */ + temp = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + temp->Stat._byte |= _SIE; + } + + /* enable handshake for Non-Isochronous Endpoints */ + ep_ctrl[direction] |= ((ep_ptr->type != USB_ISOCHRONOUS_PIPE) ? + HSHK_EN:0x00); + /* set the EndPoint Control MCU Register*/ + *((&USB0_ENDPT0) + (4 * ep_num)) |= ep_ctrl[direction]; +#else /* HIGH_SPEED_DEVICE */ + unsigned char mult; + + /* No need to initialize EP0 */ + if (ep_ptr->ep_num == CONTROL_ENDPOINT) + return USB_OK; + + switch (ep_ptr->type & 0x3) { + case EP_TRANSFER_TYPE_CONTROL: + case EP_TRANSFER_TYPE_BULK: + case EP_TRANSFER_TYPE_INTERRUPT: + mult = 0; + break; + case EP_TRANSFER_TYPE_ISOCHRONOUS: + /* Calculate the ISO transfer High-Bandwidth Pipe Multiplier + * The ISO endpoints, must set Mult 1, 2, 3 for high speed + * and only 1 for full speed + */ +#ifdef ULPI_FORCE_FULLSPEED + mult = 1; +#else + mult = (unsigned char)(1 + (((ep_ptr->size) >> 11) & 0x03)); +#endif + } + + /* setup dQH */ + usbd_ep_qh_init(controller_ID, ep_ptr->ep_num, ep_ptr->direction, ep_ptr->size, flag, mult, 0xDEAD0001); + + /* enable endpoint */ + usbd_ep_setup(controller_ID, ep_ptr->ep_num, ep_ptr->direction, ep_ptr->type); +#endif /* HIGH_SPEED_DEVICE */ + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Cancel_Transfer + * + * @brief The function cancels any pending Transfers which ahve not been sent + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USBERR_NOT_SUPPORTED : Always + ****************************************************************************** + * This function just returns Error Code not supported + *****************************************************************************/ +uint_8 USB_DCI_Cancel_Transfer ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ +#if !HIGH_SPEED_DEVICE +#ifdef LONG_TRANSACTION + uint_8 status= USBERR_UNKNOWN_ERROR; + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + uint_8 bdtelem_index = (uint_8)TRANSFER_INDEX(bdt_index); + UNUSED(handle); + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + P_BDT_ELEM bdt_elem = &g_bdt_elem[bdtelem_index]; + P_BUFF_DSC buffer_dsc = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + P_BUFF_DSC buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index ^ 1]; + /* Clear SIE Control Bit for both buffers*/ + buffer_dsc->Stat._byte &= ~_SIE; + buffer_dsc_alt->Stat._byte &= ~_SIE; + bdt_elem->app_len = (USB_PACKET_SIZE)UNINITIALISED_VAL; + + status = USB_OK; + } + return status; +#else + return USBERR_NOT_SUPPORTED; +#endif +#else // HIGH_SPEED_DEVICE +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif + return USBERR_NOT_SUPPORTED; +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Deinit_EndPoint + * + * @brief The function de initializes an endpoint + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USB_OK : When successfull + * USBERR_EP_DEINIT_FAILED : When unsuccessfull + ****************************************************************************** + * + * This function un-intializes the endpoint by clearing the corresponding + * endpoint control register and then clearing the bdt elem. + * + *****************************************************************************/ +uint_8 USB_DCI_Deinit_EndPoint ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (ep_num, direction, + USB_RAM_EVEN_BUFFER); + uint_8 bdtelem_index = (uint_8)TRANSFER_INDEX(bdt_index); + + /* in case the bdt_index is invalid*/ + if(bdt_index == INVALID_BDT_INDEX) + { + return USBERR_EP_DEINIT_FAILED; + } + USB_DCI_Cancel_Transfer(&controller_ID, ep_num, direction); + /* delete buffer space for both even and odd buffers */ + g_bdt_address -= (g_bdt_elem[bdtelem_index].len); + + /* Disable endpoint */ + *((&USB0_ENDPT0) + (4 * ep_num)) = EP_DISABLE; + + /* un-initialize the bdt_elem structure for this endpoint */ + g_bdt_elem[bdtelem_index].len = (uint_16)UNINITIALISED_VAL; + g_bdt_elem[bdtelem_index].addr = (uint_32)UNINITIALISED_VAL; +#else // HIGH SPEED + uint_32 reg; + + if(ep_num<1) + return USB_INVALID; + + // clear qhd + dqh_setup_t *dqh_word = (dqh_setup_t*)usbd_get_dqh(controller_ID, ep_num, direction); + memset((void *)dqh_word, 0, SIZE_OF_QHD); + + // clear endpoint register + reg = USBHS_EPCR(ep_num-1); + USBHS_EPCR(ep_num-1) &= ~reg; + + // flush endpoint Tx(IN) buffer + if(direction) + USBHS_EPFLUSH |= USBHS_EPFLUSH_FETB(ep_num-1); + // flush endpoint Rx(OUT) buffer + else + USBHS_EPFLUSH |= USBHS_EPFLUSH_FERB(ep_num-1); +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Stall_EndPoint + * + * @brief The function stalls an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function stalls the endpoint by setting Endpoint BDT + *****************************************************************************/ +void USB_DCI_Stall_EndPoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number to stall */ + uint_8 direction /* [IN] Direction to stall */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + bdt_index = bdt_elem->bdtmap_index; + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + (void)USB_DCI_Cancel_Transfer(handle, endpoint_number, direction); + + /* Stall endpoint */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte |= (_SIE | _BDTSTALL); + } +#else // HIGH SPEED + // check if it is control endpoint + if(endpoint_number == 0){ + // stall both directions + USBHS_EPCR0 |= USBHS_EPCR0_TXS_MASK|USBHS_EPCR0_RXS_MASK; + }else{ + + USBHS_EPCR(endpoint_number-1) |= direction?USBHS_EPCR0_TXS_MASK:USBHS_EPCR0_RXS_MASK; + } +#endif + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Unstall_EndPoint + * + * @brief The function unstalls an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function unstalls the endpoint by clearing Endpoint Control Register + * and BDT + *****************************************************************************/ +void USB_DCI_Unstall_EndPoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number to unstall */ + uint_8 direction /* [IN] Direction to unstall */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + bdt_index = bdt_elem->bdtmap_index; + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + ENDPT0STR *endpoint = (ENDPT0STR*)(&USB0_ENDPT0 + (4 * endpoint_number)); + + /* Enable ENDPTx for non control endpoints */ + /* For Control Endpoint the default Value 0x0D */ + if(endpoint_number != CONTROL_ENDPOINT) + { + uint_8 endpt; + /* Enable handshaking for non isochronous endpoint */ + endpt = (uint_8)((bdt_elem->type != USB_ISOCHRONOUS_PIPE) ? + HSHK_EN:0); + /* + Enable the endpoint in the specified direction and disable + control tranfers (valid only in case the endpoint is + bidirectional) + */ + endpt |= (uint_8)(EP_CTL_DIS | + ((direction == USB_SEND)?EP_IN:EP_OUT)); + endpoint->Byte |= endpt; + } + /* Clear Endpoint Stall bit is endpoint control register */ + endpoint->Bits.EP_STALL = 0; + + /* Unstall endpoint by clearing stall bit in BDT */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte &= ~(_SIE | _BDTSTALL); + /* We Require DATA0 PID to be zero on unstall */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte = _DATA0; + if(direction == USB_RECV) + { + /* Initiate Next receive Transfer */ + USB_DCI_Recv_Data(handle, endpoint_number, NULL, 0); + } + } +#else + // todo: + // This function unstalls the endpoint by clearing Endpoint Control Register + // and QH + if(endpoint_number == 0){ + // unstall both directions + USBHS_EPCR0 &= ~(direction ? USBHS_EPCR0_TXS_MASK:USBHS_EPCR0_RXS_MASK); + }else{ + USBHS_EPCR(endpoint_number-1) &= ~(direction?USBHS_EPCR_TXS_MASK:USBHS_EPCR_RXS_MASK); + } +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif +#endif + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Get_Setup_Data + * + * @brief The function copies Setup Packet from USB RAM to application buffer + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * + * @return None + * + ****************************************************************************** + * Copies setup packet from USB RAM to Application Buffer + *****************************************************************************/ +void USB_DCI_Get_Setup_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number for the transaction */ + uint_8_ptr buffer_ptr /* [IN] Pointer to the buffer into which to read data */ +) +{ + +#if !HIGH_SPEED_DEVICE + uint_8_ptr addr; + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_RECV, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + UNUSED(handle); + bdt_index = bdt_elem->bdtmap_index; + + /* address correponding to the endpoint */ + addr = (uint_8_ptr)SWAP32(g_bdtmap->ep_dsc[bdt_index].addr); + + /* copy bdt buffer to application buffer */ + (void)memcpy(buffer_ptr, addr, USB_SETUP_PKT_SIZE); + return; +#else // HIGH SPEED +#if USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Get_Transfer_Status + * + * @brief The function retrieves the Transfer status of an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USBERR_TR_FAILED : When unsuccessful + * USB_STATUS_IDLE : No transfer on endpoint + * USB_STATUS_DISABLED : endpoint is disabled + * USB_STATUS_STALLED : endpoint is stalled + * USB_STATUS_TRANSFER_IN_PROGRESS : When SIE has control of BDT + ****************************************************************************** + * + * This function retrieves the transfer status of the endpoint by checking the + * BDT as well as the endpoint control register + * + *****************************************************************************/ +uint_8 USB_DCI_Get_Transfer_Status ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ + uint_8 status = USB_STATUS_DISABLED; + +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + UNUSED(handle); + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + uint_8 ep_control = (uint_8)(*((&USB0_ENDPT0)+4*endpoint_number)); + + status = USB_STATUS_IDLE; + + /* Check for direction in endpoint control register */ + if((ep_control & (EP_IN|EP_OUT)) == EP_DISABLE) + { + status = USB_STATUS_DISABLED; + } + /* Check for stall bit in endpoint control register */ + else if ((ep_control & EPCTL_STALL) == EPCTL_STALL) + { + status = USB_STATUS_STALLED ; + } + /* Check whether SIE has control of BDT */ + else if ((g_bdtmap->ep_dsc[bdt_index].Stat.SieCtlBit.own == 1) + || (g_bdtmap->ep_dsc[bdt_index ^ 1].Stat.SieCtlBit.own == 1)) + { + status = USB_STATUS_TRANSFER_IN_PROGRESS; + } + } +#else +#if USART_DEBUG + printf("%s, ep_num is %d\n", __func__, endpoint_number); +#endif /* USART_DEBUG */ + status = USB_OK; +#endif /* HIGH_SPEED_DEVICE */ + return status; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Clear_DATA0_Endpoint + * + * @brief The function clear the DATA0/1 bit + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function clear the DATA0/1 bit + *****************************************************************************/ +void USB_DCI_Clear_DATA0_Endpoint ( + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ + +#if !HIGH_SPEED_DEVICE + + uint_8 bdt_index = USB_DCI_Validate_Param(endpoint_number, direction, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + bdt_index = bdt_elem->bdtmap_index; + + /*Check for a valid bdt index */ + if (bdt_index != INVALID_BDT_INDEX) + { + //ENDPT0STR *endpoint = (ENDPT0STR*)(&USB0_ENDPT0 + (4 * endpoint_number)); /* << EST not used */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte = _DATA0; + } + return; +#else // HIGH SPEED +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Recv_Data + * + * @brief The function retrieves data received on an RECV endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * @param size : Size of the buffer + * + * @return status + * USB_OK : When successful + * USBERR_RX_FAILED : When unsuccessful + ****************************************************************************** + * This function retrieves data received data on a RECV endpoint by copying it + * from USB RAM to application buffer + *****************************************************************************/ +uint_8 USB_DCI_Recv_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number for the transaction */ + uchar_ptr buffer_ptr, /* [OUT] Pointer to the buffer into which to receive data */ + uint_32 size /* [IN] Number of bytes to receive */ +) +{ + uint_8 status = USBERR_RX_FAILED; +#if !HIGH_SPEED_DEVICE + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_RECV, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + UNUSED(handle); + + /* For selecting even/odd buffer */ + bdt_index = bdt_elem->bdtmap_index; + + if(bdt_index != INVALID_BDT_INDEX) + { + P_BUFF_DSC buffer_dsc = &g_bdtmap->ep_dsc[bdt_index ^ 1]; + P_BUFF_DSC buffer_dsc_alt = NULL; + + /* Check for valid bdt index */ + if(bdt_elem->len != (uint_16)UNINITIALISED_VAL) + { + /* Does MCU owns it */ + if(buffer_dsc->Stat.SieCtlBit.own == FALSE) + { + if(size == 0) + { + /* + Give control to the other buffer to recv the next + packet + */ + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt->cnt = SWAP16(bdt_elem->len); + buffer_dsc_alt->addr = SWAP32(bdt_elem->addr); + + /* Give the ownership to SIE and TOGGLE DATA BIT */ + buffer_dsc_alt->Stat._byte = (uint_8)( + (buffer_dsc_alt->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + return USB_OK; + } + /* adjust size based on the input at the init endpoint */ +#ifdef LONG_RECEIVE_TRANSACTION + /* Initialise transfer */ + bdt_elem->app_len = size; + bdt_elem->app_buffer = buffer_ptr; +#endif + if(size > bdt_elem->len) + { + size = bdt_elem->len; + } + +#ifdef LONG_RECEIVE_TRANSACTION + bdt_elem->curr_offset = 0; +#endif + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt->cnt = SWAP16(size); + buffer_dsc_alt->addr = SWAP32((uint_32)buffer_ptr); + buffer_dsc_alt->Stat._byte = (uint_8)( + (buffer_dsc_alt->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + status = USB_OK; + } + } + } + return status; +#else + if (endpoint_number != 0) + { + status = usbd_receive_data_epxout(0, (unsigned int)buffer_ptr, endpoint_number, size); + } + else + status = usbd_receive_data_ep0out(0, (unsigned int)buffer_ptr, size); + + if (status != USB_SUCCESS) + { + return USBERR_RX_FAILED; + } + else + { + return USB_OK; + } +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Send_Data + * + * @brief The function configures Controller to send data on an SEND endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * @param size : Size of the buffer + * + * @return status + * USB_OK : When successfull + * USBERR_TX_FAILED : When unsuccessfull + ****************************************************************************** + * This function configures Controller to send data on a SEND endpoint by + * setting the BDT to send data. + *****************************************************************************/ +uint_8 USB_DCI_Send_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uchar_ptr buffer_ptr, /* [IN] Application buffer pointer */ + uint_32 size /* [IN] Size of the buffer */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_8 status = USBERR_TX_FAILED; + P_BUFF_DSC buffer_dsc; + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_SEND, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + UNUSED(handle); + + if(bdt_index == INVALID_BDT_INDEX) + return USBERR_TX_FAILED; + + /* Send Data After Toggling Buffer */ + bdt_index = (uint_8)bdt_elem->bdtmap_index; + + buffer_dsc = &g_bdtmap->ep_dsc[bdt_index]; + + /* Does MCU owns it and it is not stalled */ + if(!((buffer_dsc->Stat.SieCtlBit.own) ||/* For MCU: own is 0 */ + (*(&USB0_ENDPT0 + (endpoint_number * 4)) & ENDPT_EP_STALL_MASK))) + { + /* Now configure buffer_dsc->addr and buffer_dsc->cnt */ +#ifdef LONG_SEND_TRANSACTION + /* Initialize transfer */ + bdt_elem->app_len = size; + bdt_elem->app_buffer = buffer_ptr; + bdt_elem->curr_offset = 0; + + /* Prepare for send */ + USB_DCI_Prepare_Send_Data(buffer_dsc, bdt_elem); +#else + buffer_dsc->addr = SWAP32(buffer_ptr); + + /* Adjust size based on the input at the init endpoint */ + if((uint_16)size > bdt_elem->len) + { + buffer_dsc->cnt = SWAP16(bdt_elem->len); + } + else + { + buffer_dsc->cnt = SWAP16((uint_16)size); + } +#endif + if(endpoint_number == CONTROL_ENDPOINT) + { + /* Set up the control endpoint bdt for next packet */ + buffer_dsc->Stat._byte = (_SIE | _DATA1 | _DTS); + } + else + { + buffer_dsc->Stat._byte = (uint_8)( + (buffer_dsc->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + } + + status = USB_OK; + } /* Does MCU own IN BDT */ + return status; +#else // HIGH SPEED + usb_status_t status; + + if (endpoint_number != 0) { + status = usbd_send_data_epxin(0, (unsigned int)buffer_ptr, endpoint_number, size); + } + + /* Send descriptor - Data Phase */ + //zlt is false=>not zero length packet, send dev descriptor to host. + else + status = usbd_send_data_ep0in(0, (unsigned int)buffer_ptr, size, 0); + + if (status != USB_SUCCESS) + return USBERR_TX_FAILED; + + return USB_OK; +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Set_Address + * + * @brief The function configures Controller to send data on an SEND endpoint + * + * @param handle : USB Device handle + * @param address : Controller Address + * + * @return None + * + ****************************************************************************** + * Assigns the Address to the Controller + *****************************************************************************/ +void USB_DCI_Set_Address ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 address /* [IN] Address of the USB device */ +) +{ + + UNUSED(handle); + + /* set the address */ +#if !HIGH_SPEED_DEVICE + USB0_ADDR = address; +#else + USBHS_DEVICEADDR = USBHS_DEVICEADDR_USBADR(address); +#endif + + _usb_device_set_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + USB_STATE_ADDRESS); + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Shutdown + * + * @brief The function shuts down the controller + * + * @param handle : USB Device handle + * + * @return None + * + ****************************************************************************** + * Resets USB Device Controller + *****************************************************************************/ +void USB_DCI_Shutdown ( + _usb_device_handle handle /* [IN] USB Device handle */ +) +{ + UNUSED(handle); +#if !HIGH_SPEED_DEVICE + /* Reset the Control Register */ + USB0_CTL = 0; + /* Initiate Reset in the USB Control0 Register */ + #ifndef OTG_BUILD + + USB0_USBTRC0 = _USBRESET; + #endif + + _usb_device_set_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + USB_STATE_UNKNOWN); + return; +#else +#if USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Assert_Resume + * + * @brief The function makes the Controller start USB RESUME signaling + * + * @param handle : USB Device handle + * + * @return None + * + ****************************************************************************** + * + * This function starts RESUME signalling and then stops it after some delay. + * In this delay make sure that COP is reset. + * + *****************************************************************************/ +void USB_DCI_Assert_Resume ( + _usb_device_handle handle /* [IN] USB Device handle */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_16 delay_count; + + /* Clear SUSP Bit from USB_CTRL */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + + (void)handle; + + /* Reset Low Power RESUME enable */ + USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + + USB_DCI_WAKEUP + + USB0_CTL |= USB_CTL_RESUME_MASK; /* Start RESUME signaling and make SUSPEND bit 0*/ + + delay_count = ASSERT_RESUME_DELAY_COUNT; /* Set RESUME line for 1-15 ms*/ + + do + { + delay_count--; + Watchdog_Reset(); /* Reset the COP */ + }while(delay_count); + + USB0_CTL &= ~USB_CTL_RESUME_MASK; /* Stop RESUME signalling */ + + return; +#else +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_Bus_Token_Cpl_Handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param stat : BDT stat byte + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +#if !HIGH_SPEED_DEVICE +void USB_Bus_Token_Cpl_Handler ( + uint_8 stat, /* [IN] Value of STAT register */ + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + uint_8 bdt_index = 0 ; + P_BUFF_DSC buffer_dsc = NULL; + P_BUFF_DSC buffer_dsc_alt = NULL;/* stores data of alternate buffer */ + P_BDT_ELEM bdt_elem = NULL; + boolean odd = (boolean)((stat & 0x04) >> 2); + + /* Get the direction from STAT register */ + event->direction = (uint_8)((stat & ENDPOINT_DIRECTION_MASK) >> + ENDPOINT_DIRECTION_SHIFT); + + + /* Get bdt index corresponding to endpoint number and direction */ + bdt_index = USB_DCI_Get_BDT_Index(event->ep_num,event->direction, odd); + + buffer_dsc = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index ^ 1]; + + bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + /* Get address from BDT */ + event->buffer_ptr = (uint_8_ptr)SWAP32(buffer_dsc->addr); + + /* Get len from BDT */ + event->len = SWAP16(buffer_dsc->cnt); + + /* Prepare for Next USB Transaction */ + bdt_index = (uint_8)(bdt_elem->bdtmap_index ^ 1); + bdt_elem->bdtmap_index = bdt_index; + + /* Toggle Data PID*/ + buffer_dsc_alt->Stat._byte = (uint_8)((buffer_dsc->Stat.McuCtlBit.data ^ 1) << 6); + + if(event->direction == USB_SEND) + { + if(event->ep_num == CONTROL_ENDPOINT) + { + /* for Control Endpoint */ + /* For Transfer Direction Host to Device */ + if(g_trf_direction == USB_RECV) + { + /* + Enters here for first time after Set_Address TRANSFER + Completed + */ + /* make Transfer Direction UNKNOWN */ + g_trf_direction = USB_TRF_UNKNOWN; + /* Cancel any pending Transfers on RECV Control Endpoint*/ + USB_DCI_Cancel_Transfer(&(event->controller_ID), (uint_8)CONTROL_ENDPOINT, + (uint_8)USB_RECV); + /* We Require DATA0 PID for Setup Token */ + buffer_dsc_alt->Stat._byte = _DATA0; + /* Prepare for Next SETUP PACKET Receive */ + USB_DCI_Recv_Data(&(event->controller_ID), + CONTROL_ENDPOINT, + NULL,0); + + } + }/* ep_num is CONTROL ENDPOINT */ + +#ifdef LONG_SEND_TRANSACTION + if( (g_trf_direction == USB_SEND) || + (event->ep_num != CONTROL_ENDPOINT) ) + { + /* update the request */ + bdt_elem->curr_offset += event->len; + /* + Initiate next USB SEND if: + 1. More Data is still pending OR + 2. Send Data == Endpoint Size AND + 3. Zero Termination Flag is TRUE + */ + if((bdt_elem->app_len > bdt_elem->curr_offset) || + (((uint_8)event->len == bdt_elem->len) && (bdt_elem->flag == TRUE)) + ) + { + /* send next Req */ + USB_DCI_Prepare_Send_Data(buffer_dsc_alt, bdt_elem); + + /* give the ownership to SIE and TOGGLE DATA BIT */ + buffer_dsc_alt->Stat._byte = (uint_8)( + ((buffer_dsc_alt->Stat.McuCtlBit.data) << 6) | + _SIE | _DTS);; + return; + } + else + { + event->buffer_ptr = bdt_elem->app_buffer; + event->len = bdt_elem->curr_offset; + } + } +#endif + }/* End of SEND loop */ + else /* direction IS USB_RECV */ + { + if(event->ep_num == CONTROL_ENDPOINT) + { + /* for Control Endpoint */ + if(buffer_dsc->Stat.RecPid.pid == USB_SETUP_TOKEN) + { + /* set setup phase */ + event->setup = TRUE; + /* Transfer direction of next packet */ + g_trf_direction = (uint_8)((uint_8) + (event->buffer_ptr[0]) >> 7); + } + else if(g_trf_direction == USB_SEND) + { + /* make Transfer Direction UNKNOWN */ + g_trf_direction = USB_TRF_UNKNOWN; + /* Cancel any pending Transfers on SEND Control Endpoint*/ + USB_DCI_Cancel_Transfer(&(event->controller_ID), (uint_8)CONTROL_ENDPOINT, + (uint_8)USB_SEND); + /* We Require DATA0 PID for Setup Token */ + buffer_dsc_alt->Stat._byte = _DATA0; + /* Prepare for Next SETUP PACKET Receive */ + USB_DCI_Recv_Data(&(event->controller_ID), + CONTROL_ENDPOINT, + NULL,0); + } + } /* ep_num is CONTROL ENDPOINT */ + +#ifdef LONG_RECEIVE_TRANSACTION + /* For NON CONTROL ENDPOINT only */ + if(bdt_elem->app_len != (USB_PACKET_SIZE)UNINITIALISED_VAL) + { + /* on control endpoint the data is only 8 bytes */ + USB_PACKET_SIZE size = event->len; + bdt_elem->curr_offset += size; + + /* + Initiate next USB RECV if: + 1. More Data is still pending OR + 2. Received Data == Endpoint Size AND + 3. Zero Termination Flag is TRUE + */ + if( + ( (size == bdt_elem->len) && + (bdt_elem->app_len > bdt_elem->curr_offset) + ) || + ( (bdt_elem->app_len)&& + (!(bdt_elem->app_len % bdt_elem->len)) && + (bdt_elem->flag == TRUE) + ) + ) + { + /* send next IO */ + uint_16 count; + count = (uint_16)(((bdt_elem->app_len - bdt_elem->curr_offset) + > bdt_elem->len) ? bdt_elem->len : + (bdt_elem->app_len - bdt_elem->curr_offset)); + if(count == 0) + { + /* For Zero byte Packet Receive */ + buffer_dsc_alt->addr = SWAP32(bdt_elem->addr); + buffer_dsc_alt->cnt = 0; + } + else + { + buffer_dsc_alt->addr = SWAP32((uint_32)(bdt_elem->app_buffer + bdt_elem->curr_offset)); + buffer_dsc_alt->cnt = SWAP16(count); + } + + /* give the ownership to SIE and Toggle DATA bit*/ + buffer_dsc_alt->Stat._byte = (uint_8)(( + (buffer_dsc_alt->Stat.McuCtlBit.data) << 6) | + _SIE | _DTS); + return; + } + else /* request completed */ + { + /* populate buffer structure */ + event->buffer_ptr = bdt_elem->app_buffer; + event->len = bdt_elem->curr_offset; + bdt_elem->app_len = (USB_PACKET_SIZE)UNINITIALISED_VAL; + } + } +#endif + } /* End of RECV loop */ + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); + + return; +} +#endif // HIGH_SPEED_DEVICE + +#if HIGH_SPEED_DEVICE +/**************************************************************************//*! + * */ +uint_32 sof_counter = 0; +static uint_32 micro_sof_counter = 0; +void USBHS_ISR(void){ + uint_32 usbsts; + uint_32 reg; + USB_DEV_EVENT_STRUCT event; + + // get interrupt status + reg = USBHS_USBINTR; + usbsts = USBHS_USBSTS & reg; + + // clear interrupt status + USBHS_USBSTS |= usbsts; + + // initialize event structure + event.controller_ID = g_dci_controller_Id; + event.setup = FALSE; + event.buffer_ptr = NULL; + event.len = 0; + event.direction = USB_RECV; + event.errors = NO_ERRORS; + event.ep_num = (uint_8)UNINITIALISED_VAL; + + // handle SOF + if(usbsts & USBHS_USBSTS_SRI_MASK){ + //USBHS_USBSTS |= USBHS_USBSTS_SRI_MASK; +#ifdef ULPI_FORCE_FULLSPEED + sof_counter++; +#else + if (++micro_sof_counter == 8){ + //sof_counter++; + //micro_sof_counter = 0; + } +#endif + } + + // handle Suspend + if (usbsts & USBHS_USBSTS_SLI_MASK){ + USB_Device_Call_Service(USB_SERVICE_SUSPEND, &event); + return; + } + + // handle Bus Reset + if (usbsts & USBHS_USBSTS_URI_MASK){ + // handle reset + USB_Bus_Reset_Handler(); + + // notify device layer + USB_Device_Call_Service(USB_SERVICE_BUS_RESET, &event); + return; + } + + // handle Transaction Complete + if (usbsts & USBHS_USBSTS_UI_MASK){ + if (!USBHS_EPSETUPSR && !USBHS_EPCOMPLETE){ +#ifdef USART_DEBUG + printf("Warning: unexpected UI interrupt\n"); +#endif /* USART_DEBUG */ + } + + // Handle dTD complete interrupt. + // Must process EP complete events first, because setup complete events + // trigger stack to re-prime endpoints. + if(USBHS_EPCOMPLETE) + usbd_ep_complete_handler(&event); + + // Handle setup compete packet interrupt + if(USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(1)) + usbd_setup_packet_handler(&event); + + // + if( (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(2))|| + (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(4))|| + (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(8))){ +#if USART_DEBUG + printf(""); +#endif /* USART_DEBUG */ + } + } + + // handle Port Change + if (usbsts & USBHS_USBSTS_PCI_MASK){ + usbd_port_change(&event); + } + + // handle USB Error + if (usbsts & USBHS_USBSTS_UEI_MASK){ +#ifdef USART_DEBUG + printf("USBHS: Error\n"); +#endif + // Notify Device Layer of ERROR Event to error service + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + } + + // handle USB System Error + if (usbsts & USBHS_USBSTS_SEI_MASK){ +#ifdef USART_DEBUG + printf("USBHS: System Error\n"); +#endif + // Notify Device Layer of ERROR Event to error service + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + } + +} +#endif // HIGH_SPEED_DEVICE + +/**************************************************************************//*! + * + * @name USB_ISR + * + * @brief The function handles USB interrupts on the bus. + * + * @param None + * + * @return None + * + ****************************************************************************** + * This function is hooked onto interrupt 69 and handles the USB interrupts. + * After handling the interrupt it calls the Device Layer to notify it about + * the event. + *****************************************************************************/ +#if !HIGH_SPEED_DEVICE +void USB_ISR(void) +{ + /* Which interrupt occured and also was enabled */ + uint_8 v1 = USB0_ISTAT; + uint_8 v2 = USB0_INTEN; + uint_8 intr_stat = (uint_8)(v1 & v2); + uint_8 stat = (uint_8)USB0_STAT; + USB_DEV_EVENT_STRUCT event; + uint_8 dev_state = USB_STATUS_UNKNOWN; + + /* initialize event structure */ + event.controller_ID = g_dci_controller_Id; + event.setup = FALSE; + event.buffer_ptr = NULL; + event.len = 0; + event.direction = USB_RECV; + event.errors = NO_ERRORS; + + event.ep_num = (uint_8)UNINITIALISED_VAL; + + /* Get the device state from the Device Layer */ + (void)_usb_device_get_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + &dev_state); + + /* if current device state is SUSPEND and Low Power Resume Flag set */ + if((USB0_USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) && (dev_state == USB_STATE_SUSPEND)) + { + /* Clear SUSP Bit from USB_CTRL */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + + /* Reset Low Power RESUME enable */ + USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + } + + /* SOF received */ + if(SOF_TOKEN_FLAG(intr_stat)) + { + uint_16 sof_count; + uint_16 tmp1, tmp2, tmp3; + tmp1 = USB0_FRMNUMH; + tmp2 = FRAME_HIGH_BYTE_SHIFT; + tmp3 = USB0_FRMNUML; + /* Clear SOF Interrupt */ + USB0_ISTAT = USB_ISTAT_SOFTOK_MASK; + sof_count = (uint_16)((tmp1 << tmp2) | tmp3); + /*address of Lower byte of Frame number*/ + event.buffer_ptr = (uint_8_ptr)(&sof_count); + /* Notify Device Layer of SOF Event */ + (void)USB_Device_Call_Service(USB_SERVICE_SOF, &event); + +#ifdef USE_FEEDBACK_ENDPOINT + // set feedback rate info number + if(gNrSamples!=0) + feedback_data = gNrSamples; + gNrSamples = 0; +#endif + } + + if(BUS_RESET_FLAG(intr_stat)) + { + /* Clear Reset Flag */ + USB0_ISTAT = USB_ISTAT_USBRST_MASK; + + /* Handle RESET Interrupt */ + USB_Bus_Reset_Handler(); + + /* Notify Device Layer of RESET Event */ + (void)USB_Device_Call_Service(USB_SERVICE_BUS_RESET, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + + /* No need to process other interrupts */ + return; + } + + if(TOKEN_COMPL_FLAG(intr_stat)) + { + /* Clear TOKEN Interrupt */ + USB0_ISTAT = USB_ISTAT_TOKDNE_MASK; + + event.ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> + ENDPOINT_NUMBER_SHIFT); + + USB_Bus_Token_Cpl_Handler(stat, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + + if(ERROR_FLAG(intr_stat)) + { + /* Clear ERROR Interrupt */ + USB0_ISTAT = USB_ISTAT_ERROR_MASK; + + v1 = USB0_ERRSTAT; + v2 = USB0_ERREN; + event.errors = (uint_8)(v1 & v2); + + /* Notify Device Layer of ERROR Event to error service */ + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + + USB0_ERRSTAT = ERR_STAT_CLEAR_ALL; /*clear all errors*/ + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + + if(SLEEP_FLAG(intr_stat)) + { + /* Clear RESUME Interrupt if Pending */ + USB0_ISTAT = USB_ISTAT_RESUME_MASK; + + /* Clear SLEEP Interrupt */ + USB0_ISTAT = USB_ISTAT_SLEEP_MASK; + + /* Notify Device Layer of SLEEP Event */ + (void)USB_Device_Call_Service(USB_SERVICE_SLEEP, &event); + + /* Set Low Power RESUME enable */ + USB0_USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; + + /* Set SUSP Bit in USB_CTRL */ + USB0_USBCTRL |= USB_USBCTRL_SUSP_MASK; + + /* Enable RESUME Interrupt */ + USB0_INTEN |= USB_INTEN_RESUMEEN_MASK; +#ifdef USB_LOWPOWERMODE + /* Enter Stop3 Mode*/ + Enter_StopMode(STOP_MODE3); +#endif + } + + if(RESUME_FLAG(intr_stat)) + { + /* Clear RESUME Interrupt */ + USB0_ISTAT = USB_ISTAT_RESUME_MASK; + + /* Notify Device Layer of RESUME Event */ + (void)USB_Device_Call_Service(USB_SERVICE_RESUME, &event); + + /* Disable RESUME Interrupt */ + USB0_INTEN &= ~USB_INTEN_RESUMEEN_MASK; + } + + if(STALL_FLAG(intr_stat)) + { + uint_8 endp_status; + event.ep_num = (uint_8)UNINITIALISED_VAL; + + /* If Control Endpoint is stalled then unstall it. + For other endpoints host issues clear endpoint feature request + to unstall them */ + + /* Get Control Endpoint Status*/ + (void)_usb_device_get_status(&(event.controller_ID), + (USB_STATUS_ENDPOINT|CONTROL_ENDPOINT), + &endp_status); + if(endp_status == USB_STATUS_STALLED) + { + event.ep_num = CONTROL_ENDPOINT; + event.direction = USB_SEND; + } + + /* Clear STALL Interrupt */ + USB0_ISTAT = USB_ISTAT_STALL_MASK; + + /* Notify Device Layer of STALL Event */ + (void)USB_Device_Call_Service(USB_SERVICE_STALL, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + return; +} +#endif // HIGH_SPEED_DEVICE + +/**************************************************************************//*! + * + * @name Clear_Mem + * + * @brief The function clears memory starting from start_addr till count bytes + * + * @param start_addr : Buffer Start address + * @param count : Count of Bytes + * @param val : Value to be set + * + * @return None + ****************************************************************************** + * This function is an implementation of memset + *****************************************************************************/ +void Clear_Mem ( + uint_8_ptr start_addr, /* [OUT] Buffer Start address */ + uint_32 count, /* [IN] Count of Bytes */ + uint_8 val /* [IN] Value to be set */ +) +{ + (void)memset(start_addr, val, count); + return; +} + +#ifdef USB_LOWPOWERMODE +/**************************************************************************//*! + * + * @name Enter_StopMode + * + * @brief The function configures STOP Mode + * + * @param stop_mode : STOP MODE to be entered + * + * @return None + ****************************************************************************** + * This function configures different STOP MODES defined by the controller. + * Used to put controller into low power mode. Only STOP MODE 3 is implemented + *****************************************************************************/ +static void Enter_StopMode(STOP_MODE stop_mode) +{ + switch(stop_mode) + { + case STOP_MODE1: + /* + We enter Default Stop Mode + */ + break; + case STOP_MODE2: + /* Save IO Pin Status in a global variable + IO Pin Status is to be restored at POR. + Check if PPDC + */ + /* Set PPDC */ + break; + case STOP_MODE3: + /* Clear PPDC */ + SPMSC2_PPDC = 0; + /* Disable Low Voltage Detect */ + SPMSC1_LVDSE = 0; + break; + case STOP_MODE4: + break; + } + /* Enter STOP Mode*/ + _Stop; +} + +#endif + + +/* HIGH_SPEED_DEVICE */ +#if HIGH_SPEED_DEVICE + +extern void delay(int delayloop); + +static uint_8 K70_ULPI_SetDeviceMode(uint_8 controller_ID){ + // device init + unsigned int count = 10000; + unsigned int reg; + + // reset usb controller + reg = USBHS_USBCMD; + reg |= USBHS_USBCMD_RST_MASK; + USBHS_USBCMD = reg; + // check if reset done, port is enabled + while (USBHS_USBCMD & USBHS_USBCMD_RST_MASK); + + // enable USB work in device mode + reg = USBHS_USBMODE; + reg &= ~0x3; + reg |= 0x2; // device mode + + // Disable Setup Lockout by writing '1' to SLOM in USBMODE + reg &= ~(USBHS_USBMODE_SDIS_MASK); + // Setup Lockouts Off + reg |= USBHS_USBMODE_SLOM_MASK; + // this register can only be written once after reset + USBHS_USBMODE = reg; + + // wait for mode to be set + while (((USBHS_USBMODE & 0x3) != 0x2) && (--count)) ; + + if (count == 0) + return USBERR_INIT_FAILED; //timeout + +#ifdef ULPI_FORCE_FULLSPEED + reg = USBHS_PORTSC1; + reg |= USBHS_PORTSC1_PFSC_MASK; + USBHS_PORTSC1 = reg; /* force full speed */ +#endif + + // Configure ENDPOINTLISTADDR Pointer + USBHS_EPLISTADDR = (unsigned int)g_usbd_qh_buf & 0xfffff800; + + // Set OTG termination, controls the pulldown on DM + reg = USBHS_OTGSC; + reg |= (0x1 << 3); + USBHS_OTGSC = reg; + + // clear the usb intr status + USBHS_USBSTS = 0xffffffff; + + return USB_OK; +} + +/*! + * Initialize the USB device endpoint queue head structure + */ +static void usbd_ep_qh_init(uint_8 controller_ID, + unsigned char endpt_number, unsigned char direction, unsigned int max_pkt_len, + unsigned int zlt, unsigned char mult, uint_32 next_dtd) +{ + struct dqh_t qhead; + unsigned int total_bytes; + + memset((void*)&qhead, 0, sizeof(qhead)); + + // Initialize device queue head in system memory + if(endpt_number == CONTROL_ENDPOINT) + total_bytes = 8; // 8 bytes for the 1st setup packet + else + total_bytes = max_pkt_len; + qhead.dqh_base = usbd_get_dqh(controller_ID, endpt_number, direction); + qhead.next_link_ptr = next_dtd; + qhead.zlt = zlt; + qhead.mps = max_pkt_len; + qhead.ios = IOS_SET; + // todo: check + qhead.terminate = TERMINATE; + qhead.total_bytes = total_bytes; + qhead.ioc = IOC_SET; + qhead.status = NO_STATUS; + qhead.mult = mult; + qhead.buffer_ptr0 = 0; + qhead.current_offset = 0; + qhead.buffer_ptr1 = 0; + qhead.buffer_ptr2 = 0; + qhead.buffer_ptr3 = 0; + qhead.buffer_ptr4 = 0; + + /* Set Device Queue Head */ + usbd_setup_qhead(&qhead); + // Initialize TD list to empty + g_usbd_qh_tail[(endpt_number * 2) + direction] = NULL; +} + +/*! + * Setup the queue head for the USB device + * + * @param qhead The queue head data structure that contains the necessary configuration data + */ +static void usbd_setup_qhead(struct dqh_t *qhead) +{ + volatile struct dqh_setup_t *dqh_word = (volatile struct dqh_setup_t *)qhead->dqh_base; + + // 0x0 + // Bit31:30 Mult; Bit29 zlt; Bit26:16 mps; Bit15 ios + dqh_word->dqh_word0 = + (((uint_32)((qhead->zlt) << 29)) | + ((uint_32)((qhead->mps) << 16)) | + (((uint_32)(qhead->ios) <<15)) | + (uint_32)((qhead->mult) << 30)); + + // 0x4 + // Current dTD Pointer => for hw use, not modified by DCD software + dqh_word->dqh_word1 = 0x0; + + // 0x8 + // Next dTD Pointer + dqh_word->dqh_word2 = (((qhead->next_link_ptr) & 0xFFFFFFE0) | qhead->terminate); + + // 0xC + // Bit30:16 total_bytes; Bit15 ioc; Bit11:10 MultO; Bit7:0 status + dqh_word->dqh_word3 = + ((((uint_32)(qhead->total_bytes) & 0x7FFF) << 16) | + ((uint_32)(qhead->ioc) << 15) | + (qhead->status)); + + // 0x10 + // Bit31:12 Buffer Pointer (Page 0) + dqh_word->dqh_word4 = + ((qhead->buffer_ptr0 & 0xFFFFF000) | + (qhead->current_offset & 0xFFF)); + + // 0x14 + // Bit31:12 Buffer Pointer (Page 1) + dqh_word->dqh_word5 = (qhead->buffer_ptr1 & 0xFFFFF000); + + // 0x18 + // Bit31:12 Buffer Pointer (Page 2) + dqh_word->dqh_word6 = (qhead->buffer_ptr2 & 0xFFFFF000); + + // 0x1C + // Bit31:12 Buffer Pointer (Page 3) + dqh_word->dqh_word7 = (qhead->buffer_ptr3 & 0xFFFFF000); + + // 0x20 + // Bit31:12 Buffer Pointer (Page 4) + dqh_word->dqh_word8 = (qhead->buffer_ptr4 & 0xFFFFF000); + + // 0x24 + // Reserved + dqh_word->dqh_word9 = 0; + + // 0x28 + // Setup Buffer 0 + dqh_word->dqh_word10 = 0; + + // 0x2C + // Setup Buffer 1 + dqh_word->dqh_word11 = 0; +} + +/*! + * Setup the transfer descriptor + * + * @param td The TD data sturcture that contains the necessary configuration data + */ +static void usbd_setup_td(struct dtd_t *td) +{ + volatile struct dtd_setup_t *dtd_word = (volatile struct dtd_setup_t *)td->dtd_base; + + /* Bit31:5 Next Link Pointer ; Bit0 terminate */ + dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate); + + /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */ + dtd_word->dtd_word1 = ((unsigned int)td->total_bytes & 0x7FFF) << 16; + dtd_word->dtd_word1 |= ((unsigned int)td->ioc << 15) | (td->status); + + /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */ + dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF)); + + /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */ + dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 2 ; */ + dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 3 ; */ + dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 4 ; */ + dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000); + +} +/*! + * Get the offset of DQH from the QH buffer base + * + * @param endpt_number The end point number, start from 0 + * @param direction The In or Out endpoint + * + * @return The relative offset of DQH + * @return 0 if can't find a free DTD + */ +static unsigned int usbd_get_dqh(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction) +{ + + unsigned char *qh_buf = g_usbd_qh_buf; + + /* direction OUT = 0 and IN = 1 */ + return (unsigned int)(qh_buf + (SIZE_OF_QHD * (endpt_number * 2 + direction))); +} + +/*! + * Get the offset of DTD from the TD buffer base + * + * @param endpt_number The end point number, start from 0 + * @param direction The In or Out endpoint + * + * @return The relative offset of DTD + */ +static unsigned int usbd_get_dtd(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned int sz) +{ + /* If Maximum EPs supported in n then EPno will range from 0 to (n-1) */ + unsigned int i; + unsigned char *td_buf = g_usbd_td_buf; + + int td_index = (endpt_number * 2) + direction; + + for (i = 0; i < MAX_DTDS_PER_EP; i++) { + + if (g_usbd_td_flag[td_index][i].status == DTD_FREE || + g_usbd_td_flag[td_index][i].total_bytes == 0) { + g_usbd_td_flag[td_index][i].status = DTD_BUSY; + // printf("ep%d direction%d alloc = %d\n", endpt_number, direction, i); + g_usbd_td_flag[td_index][i].phys_td = (volatile struct dtd_setup_t *) + ((unsigned int) td_buf + + (SIZE_OF_DTD0) *(td_index) * MAX_DTDS_PER_EP + + i * (SIZE_OF_DTD0)); + g_usbd_td_flag[td_index][i].total_bytes = sz; +#if USART_DEBUG + if(endpt_number == 1){ + printf("usbd_get_dtd ep1\n"); + } + if(endpt_number == 2){ + printf("usbd_get_dtd ep2\n"); + } + if(endpt_number == 3){ + printf("usbd_get_dtd ep3\n"); + } +#endif /* USART_DEBUG */ + return (unsigned int)g_usbd_td_flag[td_index][i].phys_td ; + } + } + // todo: clear dtd and g_usbd_td_flag and point to first item +#ifdef USART_DEBUG + printf("Cannot get dTD!\n"); +#endif + return 0; +} + +static void usbd_ep_setup(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned char ep_type) +{ + if(endpt_number == CONTROL_ENDPOINT){ + return; + } + + unsigned int temp = 0; + + if (direction) { + //if (endpt_number) + temp |= USBHS_EPCR_TXR_MASK; + temp |= USBHS_EPCR_TXE_MASK; + temp |= ((unsigned int)(ep_type) << USBHS_EPCR_TXT_SHIFT); + /* configure RX endpoint as bulk(see K70 RM) */ + temp |= ((unsigned int)(2) << USBHS_EPCR_RXT_SHIFT); + } else { +// /if (endpt_number) + temp |= USBHS_EPCR_RXR_MASK; + temp |= USBHS_EPCR_RXE_MASK; + temp |= ((unsigned int)(ep_type) << USBHS_EPCR_RXT_SHIFT); + /* configure TX endpoint as bulk(see K70 RM) */ + temp |= ((unsigned int)(2) << USBHS_EPCR_TXT_SHIFT); + } + + // Initialize endpoints 1-3 + USBHS_EPCR(endpt_number-1) = temp; +} + +/**************************************************************************//*! + * + * @name usbd_setup_packet_handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +static void usbd_setup_packet_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + unsigned char setup_packet[8]; + + // Clear setup complete register + USBHS_EPSETUPSR = USBHS_EPSETUPSR; + + // Read setup packet + usbd_read_setup_packet(event->controller_ID, setup_packet); + + // Assume EP0 + event->ep_num = CONTROL_ENDPOINT; + + // Direction of setup complete is always Receive + event->direction = USB_RECV; + event->buffer_ptr = setup_packet; + event->len = sizeof(setup_packet); + event->setup = TRUE; + + /* Transfer direction of next packet */ + g_trf_direction = (uint_8)((uint_8) + (event->buffer_ptr[0]) >> 7); + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); +} + +// Read in setup packet. Assumes EP0. +static void usbd_read_setup_packet(uint_8 controller_ID, unsigned char *setup_packet) +{ + dqh_setup_t *dqh_word; + uint_32 dqh_address; + uint_32 reg; + uint_32 count = 10000; + int i; + usb_standard_device_request_t *setup_struct; + + // a. Clear setup complete register + reg = USBHS_EPSETUPSR; + USBHS_EPSETUPSR = reg; + + /* Get the Device Queue Head Address for EP0 OUT */ + dqh_address = usbd_get_dqh(controller_ID, EP0, OUT); + dqh_word = (dqh_setup_t *) dqh_address; + + do { + // b. Setup tripwire bit + USBHS_USBCMD |= USBHS_USBCMD_SUTW_MASK; + + // c. Copy the SetupBuffer into local software byte array + reg = (dqh_word->dqh_word10); + + /* This is due to the simulator bug for word variant access on EMI but actually design has word invariant access */ + for (i = 0; i < 4; i++) { + setup_packet[i] = (unsigned int)((reg >> (8 * i)) & 0xFF); + } + reg = (dqh_word->dqh_word11); + for (i = 0; i < 4; i++) { + setup_packet[i + 4] = (unsigned int)((reg >> (8 * i)) & 0xFF); + } + + //todo change to processor speed independent count + // d. Read USBCMD[SUTW] bit (if set, continue, else goto step b) + } while (!(USBHS_USBCMD & USBHS_USBCMD_SUTW_MASK) && (--count)); + + if (!count){ +#ifdef USART_DEBUG + printf("error getting setup buffer\n"); +#endif /* USART_DEBUG */ + } + + // e. Clear USBCMD[SUTW] bit + USBHS_USBCMD &= ~USBHS_USBCMD_SUTW_MASK; + + setup_struct = (usb_standard_device_request_t *)setup_packet; + if (setup_struct->bRequest == SET_ADDRESS) { + g_dci_address_state = 1; + } +} + + +static void usbd_port_change( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +){ +} + + +/**************************************************************************//*! + * + * @name usbd_dtd_handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +static void usbd_ep_complete_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + int i; + unsigned int ep_complete; + + // todo: check +#if USART_DEBUG + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(2)){ + printf("ep1: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(4)){ + printf("ep2: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(8)){ + printf("ep3: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(2)){ + printf("ep1: SEND\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(4)){ + printf("ep2: SEND\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(8)){ + printf("ep3: SEND\n"); + } +#endif /* USART_DEBUG */ + // Get and clear endpoint complete register + ep_complete = USBHS_EPCOMPLETE; + USBHS_EPCOMPLETE = ep_complete; + + // Handle all ep bits set in ep complete register + for (i = 0; i < 16; i++) + { + // Determine bit position in ep complete register + // (skip over the reserved bits) + unsigned int ep_bit = (i < 8) ? i : (i + 8); + + if (ep_complete & (1 << ep_bit)) + { + if (ep_bit < 8) + { + // Endpoint Receive Complete Event + event->direction = USB_RECV; + event->ep_num = i; + } + else + { + // Endpoint Transmit Complete Event + event->direction = USB_SEND; + event->ep_num = ep_bit - 16; + } + + if (event->ep_num == CONTROL_ENDPOINT) + { + // Control endpoint handling + usbd_ep0_complete(event); + } + else + { + // Non-control endpoint handling + usbd_dtd_complete(event); + } + } + } +} + +// Control endpoint complete handling +static void usbd_ep0_complete(USB_DEV_EVENT_STRUCT* event) +{ + volatile struct dtd_setup_t *dtd_word; + unsigned int i; + unsigned int endpt_number = event->ep_num; + unsigned int direction = event->direction; + + // Walk the TD status array to find the next completed TD + for (i = 0; i < MAX_DTDS_PER_EP; i++) + { + unsigned int td_index = (endpt_number * 2) + direction; + + // Get dTD associated with this endpoint and direction + dtd_word = g_usbd_td_flag[td_index][i].phys_td; + + // Determine if dTD is busy (not free) and completed (not active) + if ((g_usbd_td_flag[td_index][i].status == DTD_BUSY) && ((dtd_word->dtd_word1 & 0x80) != 0x80)) + { + // Mark dTD as free + g_usbd_td_flag[td_index][i].status = DTD_FREE; + + if (g_dci_address_state ==1) { + event->ep_num = CONTROL_ENDPOINT; + event->buffer_ptr = 0; + event->len = 0; + g_dci_address_state =0; + } + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); + } + } +} + +// Handle endpoint dTD complete +static void usbd_dtd_complete(USB_DEV_EVENT_STRUCT* event) +{ + volatile struct dtd_setup_t *dtd_word; + unsigned int i; + unsigned int endpt_number = event->ep_num; + unsigned int direction = event->direction; + + // todo: check +#if USART_DEBUG + if(event->ep_num == 1){ + printf("usbd_dtd_complete ep1\n"); + } + if(event->ep_num == 2){ + printf("usbd_dtd_complete ep2\n"); + } + if(event->ep_num == 3){ + printf("usbd_dtd_complete ep3\n"); + } +#endif /*USART_DEBUG */ + // Walk the TD status array to find the next completed TD + for (i = 0; i < MAX_DTDS_PER_EP; i++) + { + unsigned int td_index = (endpt_number * 2) + direction; + + // Get dTD associated with this endpoint and direction + dtd_word = g_usbd_td_flag[td_index][i].phys_td; + + // Determine if dTD is busy (not free) and completed (not active) + if ((g_usbd_td_flag[td_index][i].status == DTD_BUSY) && ((dtd_word->dtd_word1 & 0x80) != 0x80)) + { + // Get original number of bytes to transfer + unsigned int total_bytes = g_usbd_td_flag[td_index][i].total_bytes; + // Subtract number of remaining bytes not transferred + event->len = total_bytes - (dtd_word->dtd_word1 >> 16) & 0x7FFF; + event->buffer_ptr = (uint_8 *)dtd_word->dtd_word2 - event->len; + + // Mark dTD as free + g_usbd_td_flag[td_index][i].status = DTD_FREE; + + // If this was the tail, mark list as empty + if (dtd_word == g_usbd_qh_tail[td_index]) + g_usbd_qh_tail[td_index] = NULL; + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); +// break; + } + } +} + +/*! + * Receive data through EPx + * + * @param epx_data_buffer EPx receive buffer + * @param sz Number of bytes to receive + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_receive_data_epxout(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int direction = OUT; + + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, ep_num, direction, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get the total bytes to be received */ + total_bytes = sz; + +#if USART_DEBUG + if (total_bytes > 20 * 1024) + printf("Error!!! %s, size is %d\n", __func__, sz); +#endif /* USART_DEBUG */ + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = epx_data_buffer; + td.current_offset = (epx_data_buffer & 0xFFF); + td.buffer_ptr1 = (epx_data_buffer & 0xFFFFF000) + 0x1000; + td.buffer_ptr2 = (epx_data_buffer & 0xFFFFF000) + 0x2000; + td.buffer_ptr3 = (epx_data_buffer & 0xFFFFF000) + 0x3000; + td.buffer_ptr4 = (epx_data_buffer & 0xFFFFF000) + 0x4000; + + /* Set the Transfer Descriptor */ + usbd_setup_td(&td); + + // Add TD to TD list for this endpoint + direction + usbd_add_td(controller_ID, ep_num, direction, &td); + + return USB_SUCCESS; +} + +/*! + * Receive data through EP0 + * + * @param ep0_data_buffer EP0 receive buffer + * @param sz Number of bytes to receive + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_receive_data_ep0out(uint_8 controller_ID, unsigned int ep0_data_buffer, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int dqh_address; + unsigned int temp; + +// printf_info("%s, size is %d\n", __func__, sz); + + // Yi if (ep0_data_buffer != NULL) + // memset((void *)ep0_data_buffer, 0x0, 256); //todo hard-coded size + + /* Get Device Device Queue Head of the requested endpoint */ + dqh_address = usbd_get_dqh(controller_ID, EP0, OUT); + + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, EP0, OUT, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get the total bytes to be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = dtd_address + 0x20; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = ep0_data_buffer; + td.current_offset = (ep0_data_buffer & 0xFFF); + td.buffer_ptr1 = 0; + td.buffer_ptr2 = 0; + td.buffer_ptr3 = 0; + td.buffer_ptr4 = 0; + + /* Set the Transfer Descriptor */ + usbd_setup_td(&td); + + //Yi + //(*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = dtd_address; + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + /* 3. prime endpoint by writing '1' in ENDPTPRIME */ + temp = USBHS_EPPRIME; + temp |= EPOUT_PRIME; + USBHS_EPPRIME = temp; + while (USBHS_EPPRIME & EPOUT_PRIME) ; //wait prime end + + return USB_SUCCESS; +} + +// Prime endpoint +static void usbd_prime_ep(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td) +{ + unsigned int temp; + + unsigned int ep_mask = (direction == OUT ? EPOUT_PRIME : EPIN_PRIME); + // Get Device Device Queue Head of the requested endpoint + unsigned int dqh_address = usbd_get_dqh(controller_ID, ep_num, direction); + + /* Enable ZLT when data size is in multiple of Maximum Packet Size */ + /* set ZLT enable */ + if (direction == IN) + { + (*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + } + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = td->dtd_base; + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + /* 3. prime endpoint by writing '1' in ENDPTPRIME */ + temp = USBHS_EPPRIME; + temp |= ep_mask << ep_num; + USBHS_EPPRIME = temp; +} + +// Add TD to TD list and prime endpoint based on this algorithm: +// Appendix +// 5.5.3 Executing A Transfer Descriptor +// To safely add a dTD, the DCD must be follow this procedure which will handle the event where the device +// controller reaches the end of the dTD list at the same time a new dTD is being added to the end of the list. +// Determine whether the link list is empty: +// Check DCD driver to see if pipe is empty (internal representation of linked-list should indicate if any packets +// are outstanding). +// Case 1: Link list is empty +// 1. Write dQH next pointer AND dQH terminate bit to 0 as a single DWord operation. +// 2. Clear active & halt bit in dQH (in case set from a previous error). +// 3. Prime endpoint by writing '1' to correct bit position in ENDPTPRIME. +// Case 2: Link list is not empty +// 1. Add dTD to end of linked list. +// 2. Read correct prime bit in ENDPTPRIME - if '1' DONE. +// 3. Set ATDTW bit in USBCMD register to '1'. +// 4. Read correct status bit in ENDPTPRIME. (store in tmp. variable for later) [[this should be ENDPTSTATUS, not ENDPTPRIME]} +// 5. Read ATDTW bit in USBCMD register. +// If '0' goto 3. +// If '1' continue to 6. +// 6. Write ATDTW bit in USBCMD register to '0'. +// 7. If status bit read in (4) is '1' DONE. +// 8. If status bit read in (4) is '0' then Goto Case 1: Step 1. +// +static void usbd_add_td(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td) +{ + // Get the index into the TD list for this endpoint + direction + int td_index = (ep_num * 2) + direction; + + if (g_usbd_qh_tail[td_index] == NULL) + { + // Case 1: Link list is empty + + usbd_prime_ep(controller_ID, ep_num, direction, td); + } + else + { + // Case 2: Link list is not empty + + unsigned int ep_mask = (direction == OUT ? EPOUT_PRIME : EPIN_PRIME); + + // Add TD to tail next_link_ptr + // Clear Terminate bit to indicate pointer is valid + g_usbd_qh_tail[td_index]->dtd_word0 = td->dtd_base & 0xFFFFFFE0; + + // If EP is already primed, we are done + if (!(USBHS_EPPRIME & (ep_mask << ep_num))) + { + // EP not primed, check if it is active + unsigned int ep_status = 0; + unsigned int temp; + + // Use Add dTD Tripwire to properly read endpoint status register + do + { + /* write '1' to Add Tripwire (ATDTW) in USBCMD register */ + temp = USBHS_USBCMD; + temp |= (0x1 << USBHS_USBCMD_ATDTW_SHIFT); + USBHS_USBCMD = temp; + + // Read endpoint status + ep_status = USBHS_EPSR & (ep_mask << ep_num); + + } while (!USBHS_USBCMD & (0x1 << USBHS_USBCMD_ATDTW_SHIFT)); + + /* write '0' to Add Tripwire (ATDTW) in USBCMD register */ + temp = USBHS_USBCMD; + temp &= ~(0x1 << USBHS_USBCMD_ATDTW_SHIFT); + USBHS_USBCMD = temp; + + if (!ep_status) + { + // Status is inactive, so need to prime EP + usbd_prime_ep(controller_ID, ep_num, direction, td); + } + } + } + + // Make this TD the tail + g_usbd_qh_tail[td_index] = (struct dtd_setup_t *)td->dtd_base; +} + +/*! + * Send data through endpoint x + * + * @param epx_data_buffer EPx send buffer + * @param sz Number of bytes to send + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_send_data_epxin(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int direction = IN; + + /* verify Endpoint Number and address */ + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, ep_num, direction, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get Total Bytes to Be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = epx_data_buffer; + td.current_offset = (epx_data_buffer & 0xFFF); + td.buffer_ptr1 = (epx_data_buffer & 0xFFFFF000) + 0x1000; + td.buffer_ptr2 = (epx_data_buffer & 0xFFFFF000) + 0x2000; + td.buffer_ptr3 = (epx_data_buffer & 0xFFFFF000) + 0x3000; + td.buffer_ptr4 = (epx_data_buffer & 0xFFFFF000) + 0x4000; + + /* Set the transfer descriptor */ + usbd_setup_td(&td); + + // Add TD to TD list for this endpoint + direction + usbd_add_td(controller_ID, ep_num, direction, &td); + + return USB_SUCCESS; +} + +/*! + * Send data through endpoint 0 + * + * @param ep0_data_buffer EP0 send buffer + * @param sz Number of bytes to send + * @param zlt_enable If ZLT is enabled + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_send_data_ep0in(uint_8 controller_ID, + unsigned int ep0_data_buffer, unsigned int sz, + unsigned char zlt_enable) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address, dqh_address; + + /* varify Endpoint Number and address */ + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, EP0, IN, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get Device Queue head of the requested endpoint */ + dqh_address = usbd_get_dqh(controller_ID, EP0, IN); + + /* Get Total Bytes to Be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = ep0_data_buffer; + td.current_offset = (ep0_data_buffer & 0xFFF); + td.buffer_ptr1 = 0; + td.buffer_ptr2 = 0; + td.buffer_ptr3 = 0; + td.buffer_ptr4 = 0; + + /* Set the transfer descriptor */ + usbd_setup_td(&td); + + /* Enable ZLT when data size is in multiple of Maximum Packet Size */ + /* set ZLT enable */ + (*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = (dtd_address); + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + USBHS_EPPRIME |= EPIN_PRIME; + + /* 4. wait for prime complete */ + while (USBHS_EPPRIME & EPIN_PRIME); + + return USB_SUCCESS; +} +#endif /* HIGH_SPEED_DEVICE */ diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.h new file mode 100644 index 0000000..a3bc696 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dci_kinetis.h @@ -0,0 +1,311 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dci_kinetis.h + * + * @author + * + * @version + * + * @date + * + * @brief The file contains Macro's and functions needed by the DCI layer. + * + *****************************************************************************/ + +#ifndef _USB_DCI_H +#define _USB_DCI_H +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "derivative.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define BYTES_1024 (1024) +#define BYTES_512 (512) +#define ENDPT_EP_STALL_MASK (0x02) +#define FRAME_HIGH_BYTE_SHIFT (8) + +#ifdef USB_LOWPOWERMODE +typedef enum _stopmode +{ + STOP_MODE1 = 1, /* STOP MODE 1 */ + STOP_MODE2 = 2, /* STOP MODE 2 */ + STOP_MODE3 = 3, /* STOP MODE 3 */ + STOP_MODE4 = 4 /* STOP MODE 4 */ +}STOP_MODE; +#endif + +/* USBTRC0 Initialization Parameters */ +#define _USBPHYEN (0x01) /* Use internal transceiver */ +#define _USBPUEN (0x40) /* Use internal pull-up resistor */ +#define _USBREGEN (0x04) /* Use the internal regulator */ +#define _USBRESET (0x80) + +#define UCFG_VAL (_USBPUEN|_USBREGEN) + +#define CTL_RESET_VAL (0) /* value programmed to the CTL + register in RESET */ + +#define EP_CTRL (0x0C) /* Cfg Control pipe for this endpoint */ +// HIGH_SPEED_DEVICE +#if !HIGH_SPEED_DEVICE +#define EP_OUT (0x08) /* Cfg OUT only pipe for this endpoint*/ +#define EP_IN (0x04) /* Cfg IN only pipe for this endpoint */ +#endif +#define HSHK_EN (0x01) /* Enable handshake packet */ + /* Handshake should be disable for + isochorous transfer */ +#define EP_CTL_DIS (0x10) + +#define EP_DISABLE (0) + +#define TRANSFER_INDEX(x) (x>>1) + +#define MAX_EP_BUFFER_SIZE USB_MAX_EP_BUFFER_SIZE /*Max Endpoint Buffer Size*/ + +/* Macro's to check whether corresponding INT_STAT bit is set */ +#define BUS_RESET_FLAG(x) ((x) & 1) +#define ERROR_FLAG(x) ((x) & 2) +#define SOF_TOKEN_FLAG(x) ((x) & 4) +#define SLEEP_FLAG(x) ((x) & 0x10) +#define RESUME_FLAG(x) ((x) & 0x20) +#define STALL_FLAG(x) ((x) & 0x80) +#define TOKEN_COMPL_FLAG(x) ((x) & 8) + +/* Setup the controller for Remote Wakeup */ +#define USB_DCI_WAKEUP \ +{ \ + USB0_ISTAT |= USB_ISTAT_RESUME_MASK; \ + USB0_INTEN &= ~USB_INTEN_RESUMEEN_MASK; \ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; \ +} + +/* control endpoint transfer types */ +#define USB_TRF_UNKNOWN (0xFF) + + +#define BDT_MIN_BUFFER_SIZE (16) /* space occupied by smallest + buffer in BDT */ + +#define BDT_MIN_BUFFER_ADDR_INC (4) /* min offset increment + correspoding to min buffer + size */ + +#define BDT_OFFSET_SHIFT (4) /* bdt offset shift */ + +#define INVALID_BDT_INDEX (0xff)/* invalid bdt index */ + +#define ENDPOINT_NUMBER_SHIFT (4) /* endpoint shift & mask to */ +#define ENDPOINT_NUMBER_MASK (0xf0)/* use in setting and getting + status */ + +#define ENDPOINT_DIRECTION_SHIFT (3) /* direction shift & mask to */ +#define ENDPOINT_DIRECTION_MASK (0x08)/* be used for STAT byte + in BDT */ + +#define SEND_CONTROL_ENDPOINT_BDT_INDEX (2) /* BDT Index for Control Endpoint + SEND direction */ +#define RECV_CONTROL_ENDPOINT_BDT_INDEX (0) /* BDT Index for Control Endpoint + RECV direction */ + +#define EPCTL_STALL (0x02)/* Stall bit in Endpoint + Control Reg */ + +#define USB_SETUP_TOKEN (0x0d)/* Setup Token PID */ +#define USB_SETUP_DIRECTION (0x80)/* Data xfer direction + for Setup packet */ + +#define INT_STAT_CLEAR_ALL (0xbf)/* Value to clear + all Interrupts */ +#define ERR_STAT_CLEAR_ALL (0xbf)/* Value to clear + all Errors */ +#define ERR_ENB_ENABLE_ALL (0xbf)/* Value to enable + all Error Interrupts */ +#define INTENB_BUS_RESET_VAL (0x9f)/* Value to enable + Interrupts in Bus Reset */ +#define INTENB_DISABLE_ALL_VAL (0x00)/* Value to disable all + Interrupts */ + +#define MAX_USB_RAM_BUFFER_INDEX (14) /* MAX possible RAM buffer + Index */ + +#define EP_START_BUFFER_ADDR (0x08)/* First USB_RAM buffer offset*/ + +#define ASSERT_RESUME_DELAY_COUNT (20000)/* Delay for assert resume, 48MHz clock */ + +#define NO_ERRORS (0) /* Init value for error */ + +#define USB_RAM_EVEN_BUFFER (0) +#define USB_RAM_ODD_BUFFER (1) + +#define SWAP16(val) (val) + +#define SWAP32(val) (val) + +/****************************************************************************** + * Types + *****************************************************************************/ +#ifdef LONG_SEND_TRANSACTION + #define LONG_TRANSACTION +#endif + +#ifdef LONG_RECEIVE_TRANSACTION + #define LONG_TRANSACTION +#endif + +typedef union { + uint_8 Byte; + struct { + uint_8 EP_HSHK :1; /* When set this bet enables an endpoint to perform handshaking during a transaction to this endpoint. This bit will generally be set unless the endpoint is Isochronous */ + uint_8 EP_STALL :1; /* When set this bit indicates that the endpoint is stalled */ + uint_8 EP_TX_EN :1; /* This bit, when set, enables the endpoint for TX transfers */ + uint_8 EP_RX_EN :1; /* This bit, when set, enables the endpoint for RX transfers */ + uint_8 EP_CTRL_DIS :1; /* This bit, when set, disables control (SETUP) transfers. When cleared, control transfers are enabled. This applies if and only if the EP_RX_EN and EP_TX_EN bits are also set */ + uint_8 :1; + uint_8 RETRY_DIS :1; /* This is a Host mode only bit and is only present in the control register for endpoint 0 (ENDPT0) */ + uint_8 HOST_WO_HUB :1; /* This is a Host mode only bit and is only present in the control register for endpoint 0 (ENDPT0) */ + } Bits; +} ENDPT0STR; + +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) +/* This structure is used to hold endpoint paramaetes and the + transaction parameters on the IO's happening on them */ +typedef struct _BDT_ELEM +{ + uint_16 len; /* endpoint max buffer len */ + uint_32 addr; /* endpoint buffer addr in USB_RAM */ +#ifdef LONG_TRANSACTION + uint_8_ptr app_buffer; /* application buffer pointer */ + USB_PACKET_SIZE app_len; /* application buffer len */ + USB_PACKET_SIZE curr_offset; /* current offset for long transactions */ +#endif + uint_8 flag; /* zero termination flag */ + uint_8 bdtmap_index; /* Corresponding to the buffer */ + uint_8 direction; /* Direction (Send/Receive) */ + uint_8 type; /* Type of Endpoint */ +} BDT_ELEM, *P_BDT_ELEM; +#if defined(__CWCC__) + #pragma options align = reset +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma pack() +#else /* gcc */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#endif + + +uint_8 USB_DCI_DeInit(void); + + /***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Device_Call_Service( + uint_8 type, + PTR_USB_DEV_EVENT_STRUCT event +); + +#ifndef OTG_BUILD +void USB_ISR(void); +#endif + +#if HIGH_SPEED_DEVICE + /* Device Queue Head and Device Transfer Descriptor Related Defination */ + #define SIZE_OF_QHD 0x40 + #define SIZE_OF_DTD0 0x20 + #define SIZE_OF_DTD1 0x20 + #define dTD_SIZE_EPIN (SIZE_OF_DTD0 + SIZE_OF_DTD1) //0x40 + #define dTD_SIZE_EPOUT (SIZE_OF_DTD0 + SIZE_OF_DTD1) //0x40 + #define BUFFER_USED_PER_EP ((SIZE_OF_QHD + dTD_SIZE_EPIN) +(SIZE_OF_QHD + dTD_SIZE_EPOUT)) //0x100 + #define ZLT_ENABLE 0 + #define ZLT_DISABLE 1 + #define IOS_NOTSET 0 + #define IOS_SET 1 + #define IOC_NOTSET 0 + #define IOC_SET 1 + #define TERMINATE 1 + #define NOT_TERMINATE 0 + #define NO_STATUS 0 + #define ACTIVE 0x00000080 + #define EPOUT_COMPLETE 0x00000001 + #define EPIN_COMPLETE 0x00010000 + #define EPOUT_PRIME 0x00000001 + #define EPIN_PRIME 0x00010000 + #define EPOUT_ENABLE 0x00000080 + #define EPIN_ENABLE 0x00800000 + #define STALL_RX 0x00000001 + #define STALL_TX 0x00010000 + + /* Maximum packet size defination */ + #define MPS_8 8 + #define MPS_64 64 + + /* enum for endpoint numbers */ + enum { + EP0, + EP1, + EP2, + EP3, + EP4, + EP5 + }; + + enum { + OUT, + IN + }; + + /* enum for data transfer type on endpoints */ + enum { + CONTROL, + ISOCHRONOUS, + BULK, + INTERRUPT + }; + + /* Status of all transaction on USB */ + typedef enum { + USB_SUCCESS, + USB_FAILURE, + USB_INVALID = -1 /* Always Keep this entry in last */ + } usb_status_t; + + /* USB Device State which are handled by DCD */ + typedef enum { + USB_DEV_DUMMY_STATE, + USB_DEV_DEFAULT_STATE, + USB_DEV_ADDRESSED_STATE, + USB_DEV_CONFIGURED_STATE + } usb_state_t; +#endif // HIGH_SPEED_DEVICE + +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dciapi.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dciapi.h new file mode 100644 index 0000000..d190ee8 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_dciapi.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dciapi.h + * + * @author + * + * @version + * + * @date Jun-05-2009 + * + * @brief The file contains DCI api function definetions . + * + *****************************************************************************/ + +#ifndef _USB_DCIAPI_H +#define _USB_DCIAPI_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_SUPPORTED_ENDPOINTS (USB_SERVICE_MAX_EP + 1) + /* Maximum endpoints supported */ +#define MIN_SUPPORTED_ENDPOINTS (1) /* Minimum endpoints supported */ +#define DOUBLE_BUFFERED_ENPOINT_NUMBER (0) /* First double buffered endpoint */ + +#ifdef MCU_MK70F12 +#define NUM_USB_CONTROLLERS (2) +#else +#define NUM_USB_CONTROLLERS (1) +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef enum USB_Controllers_t +{ + MAX3353, + ULPI +}USB_Controllers_t; + +#if HIGH_SPEED_DEVICE +typedef struct dqh_setup_t { + unsigned int dqh_word0; + unsigned int dqh_word1; + unsigned int dqh_word2; + unsigned int dqh_word3; + unsigned int dqh_word4; + unsigned int dqh_word5; + unsigned int dqh_word6; + unsigned int dqh_word7; + unsigned int dqh_word8; + unsigned int dqh_word9; + unsigned int dqh_word10; + unsigned int dqh_word11; +} dqh_setup_t; + +typedef struct dtd_setup_t { + unsigned int dtd_word0; + unsigned int dtd_word1; + unsigned int dtd_word2; + unsigned int dtd_word3; + unsigned int dtd_word4; + unsigned int dtd_word5; + unsigned int dtd_word6; + unsigned int dtd_word7; +} dtd_setup_t; + +typedef struct dqh_t { + unsigned int dqh_base; + unsigned int next_link_ptr; + unsigned int buffer_ptr0; + unsigned int buffer_ptr1; + unsigned int buffer_ptr2; + unsigned int buffer_ptr3; + unsigned int buffer_ptr4; + unsigned short total_bytes; + unsigned short mps; + unsigned short current_offset; + unsigned char zlt; + unsigned char ios; + unsigned char terminate; + unsigned char ioc; + unsigned char status; + unsigned char mult; +} dqh_t; + +typedef struct dtd_t { + unsigned int dtd_base; + unsigned int next_link_ptr; + unsigned int buffer_ptr0; + unsigned int buffer_ptr1; + unsigned int buffer_ptr2; + unsigned int buffer_ptr3; + unsigned int buffer_ptr4; + unsigned short total_bytes; + unsigned short current_offset; + unsigned char terminate; + unsigned char ioc; + unsigned char status; +} dtd_t; + +typedef struct { + unsigned int ep_dqh_base_addrs; /* Base Address of Queue Header */ + unsigned int ep_dtd_base_addrs; /* Base Address of Transfer Descriptor */ + unsigned int ep0_buffer_addrs; /* Buffer Addres for EP0 IN */ + unsigned int buffer1_address; /* Buffer1 address for bulk transfer */ + unsigned int buffer1_status; /* Status of Buffer1 */ + unsigned int buffer2_address; /* Buffer2 address for bulk transfer */ + unsigned int buffer2_status; /* Status of Buffer2 */ +} buffer_map_t; + +/* USB standard device request*/ +typedef struct usb_standrd_device_request { + unsigned char bmRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +} usb_standard_device_request_t; + +#endif // HIGH_SPEED_DEVICE + + /***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_DCI_Init( + uint_8 controller_ID, + uint_8 bVregEn +); + + +extern uint_8 USB_DCI_Init_EndPoint( + uint_8 controller_ID, + USB_EP_STRUCT_PTR ep_ptr, + boolean double_buffered +); + +extern uint_8 USB_DCI_Init_EndPoint( + uint_8 controller_ID, + USB_EP_STRUCT_PTR ep_ptr, + boolean flag +); + +extern uint_8 USB_DCI_Cancel_Transfer( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern uint_8 USB_DCI_Deinit_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Stall_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Unstall_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Get_Setup_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr +); + +extern uint_8 USB_DCI_Get_Transfer_Status( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Clear_DATA0_Endpoint( + uint_8 ep_num, + uint_8 direction +); + +extern uint_8 USB_DCI_Recv_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern uint_8 USB_DCI_Send_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern void USB_DCI_Set_Address( + uint_8 controller_ID, + uint_8 address +); + +extern void USB_DCI_Shutdown( + uint_8 controller_ID +); + +extern void USB_DCI_Assert_Resume( + uint_8 controller_ID +); + +extern void Clear_Mem(uint_8* start_addr,uint_32 count, uint_8 val); + +#define USB_DCI_Cancel_Transfer _usb_device_cancel_transfer + +#define USB_DCI_Recv_Data _usb_device_recv_data + +#define USB_DCI_Send_Data _usb_device_send_data + +#define USB_DCI_Shutdown _usb_device_shutdown + +#define USB_DCI_Stall_EndPoint _usb_device_stall_endpoint + +#define USB_DCI_Unstall_EndPoint _usb_device_unstall_endpoint + +#define USB_DCI_Get_Transfer_Status _usb_device_get_transfer_status + +#define USB_DCI_Clear_DATA0_Endpoint _usb_device_clear_data0_endpoint + +#define USB_DCI_Get_Setup_Data _usb_device_read_setup_data + +#define USB_DCI_Set_Address _usb_device_set_address + +#define USB_DCI_Assert_Resume _usb_device_assert_resume + +#endif + + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.c new file mode 100644 index 0000000..1ba1931 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.c @@ -0,0 +1,956 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_descriptor.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief This file contains USB descriptors for Virtual COM Loopback + * Application + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "derivative.h" +#include "types.h" +#include "usb_class.h" +#include "usb_descriptor.h" + +#if (defined __MCF52xxx_H__)||(defined __MK_xxx_H__) +/* Put CFV2 descriptors in RAM */ +#define USB_DESC_CONST +#else +#define USB_DESC_CONST const +#endif + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ +/* structure containing details of all the endpoints used by this device */ +USB_DESC_CONST USB_ENDPOINTS usb_desc_ep = +{ + CDC_DESC_ENDPOINT_COUNT, + { + #if DATA_CLASS_SUPPORT + #if DIC_ISOCHRONOUS_SETTING + { + DIC_ISO_IN_ENDPOINT, + USB_ISOCHRONOUS_PIPE, + USB_SEND, + DIC_ISO_IN_ENDP_PACKET_SIZE + }, + { + DIC_ISO_OUT_ENDPOINT, + USB_ISOCHRONOUS_PIPE, + USB_RECV, + DIC_ISO_OUT_ENDP_PACKET_SIZE + } + #else + { + DIC_BULK_IN_ENDPOINT, + USB_BULK_PIPE, + USB_SEND, + DIC_BULK_IN_ENDP_PACKET_SIZE + }, + { + DIC_BULK_OUT_ENDPOINT, + USB_BULK_PIPE, + USB_RECV, + DIC_BULK_OUT_ENDP_PACKET_SIZE + } + #endif + #endif + #if CIC_NOTIF_ELEM_SUPPORT + , + { + CIC_NOTIF_ENDPOINT, + USB_INTERRUPT_PIPE, + USB_SEND, + CIC_NOTIF_ENDP_PACKET_SIZE + } + #endif + + } +}; + +uint_8 USB_DESC_CONST g_device_descriptor[DEVICE_DESCRIPTOR_SIZE] = +{ + DEVICE_DESCRIPTOR_SIZE, /* Device Descriptor Size */ + USB_DEVICE_DESCRIPTOR, /* Device Type of descriptor */ + 0x00, 0x02, /* BCD USB version */ + 0x02, /* Device Class is indicated in + the interface descriptors */ + 0x00, /* Device Subclass is indicated + in the interface descriptors */ + 0x00, /* Device Protocol */ + CONTROL_MAX_PACKET_SIZE, /* Max Packet size */ +#if 0 /* << EST */ + 0xA2,0x15, /* Vendor ID */ + 0x00,0x03, /* 0300 is our Product ID for CDC */ +#else + (0x2504&0xFF),((0x2504>>8)&0xFF), /* Vendor ID from properties */ + (0x0300&0xFF),((0x0300>>8)&0xFF), /* Product ID from properties */ +#endif + 0x02,0x00, /* BCD Device version */ + 0x01, /* Manufacturer string index */ + 0x02, /* Product string index */ + 0x03, /* Serial number string index */ + 0x01 /* Number of configurations */ +}; + +uint_8 USB_DESC_CONST g_config_descriptor[CONFIG_DESC_SIZE] = +{ + CONFIG_ONLY_DESC_SIZE, /* Configuration Descriptor Size */ + USB_CONFIG_DESCRIPTOR, /* "Configuration" type of descriptor */ + CONFIG_DESC_SIZE, 0x00, /* Total length of the Configuration descriptor */ + (uint_8)(1+DATA_CLASS_SUPPORT),/*NumInterfaces*/ + 0x01, /* Configuration Value */ + 0x00, /* Configuration Description String Index*/ +#if 0 + BUS_POWERED|SELF_POWERED|(REMOTE_WAKEUP_SUPPORT<>1), /* Current draw from bus, e.g. is in 2 mA units */ + + /* CIC INTERFACE DESCRIPTOR */ + IFACE_ONLY_DESC_SIZE, + USB_IFACE_DESCRIPTOR, + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + CIC_ENDP_COUNT, /* management and notification(optional)element present */ + 0x02, /* Communication Interface Class */ + CIC_SUBCLASS_CODE, + CIC_PROTOCOL_CODE, + 0x00, /* Interface Description String Index*/ + + /* CDC Class-Specific descriptor */ + 0x05, /* size of Functional Desc in bytes */ + USB_CS_INTERFACE, /* descriptor type*/ + HEADER_FUNC_DESC, + 0x10, 0x01, /* USB Class Definitions for CDC spec release number in BCD */ + + 0x05, /* Size of this descriptor */ + USB_CS_INTERFACE, /* descriptor type*/ + CALL_MANAGEMENT_FUNC_DESC, + 0x01,/*may use 0x03 */ /* device handales call management itself(D0 set) + and will process commands multiplexed over the data interface */ + 0x01, /* Indicates multiplexed commands are + handled via data interface */ + + 0x04, /* Size of this descriptor */ + USB_CS_INTERFACE, /* descriptor type*/ + ABSTRACT_CONTROL_FUNC_DESC, + 0x06, /*may use 0x0F */ /* Device Supports all commands for ACM - CDC + PSTN SubClass bmCapabilities */ + + 0x05, /* size of Functional Desc in bytes */ + USB_CS_INTERFACE, /* descriptor type*/ + UNION_FUNC_DESC, + 0x00, /* Interface Number of Control */ + 0x01 /* Interface Number of Subordinate (Data Class) Interface */ + +#if CIC_NOTIF_ELEM_SUPPORT /*Endpoint descriptor */ + , /* Comma Added if NOTIF ELEM IS TO BE ADDED */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + CIC_NOTIF_ENDPOINT|(USB_SEND << 7), + USB_INTERRUPT_PIPE, + CIC_NOTIF_ENDP_PACKET_SIZE, 0x00, + 0x0A +#endif + +#if DATA_CLASS_SUPPORT + , /* Comma Added if DATA_CLASS_DESC IS TO BE ADDED */ + IFACE_ONLY_DESC_SIZE, + USB_IFACE_DESCRIPTOR, + (uint_8)(0x00+DATA_CLASS_SUPPORT), /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + DIC_ENDP_COUNT, /* notification element included */ + 0x0A, /* DATA Interface Class */ + 0x00, /* Data Interface SubClass Code */ + DIC_PROTOCOL_CODE, + 0x00, /* Interface Description String Index*/ + + #if ! DIC_ISOCHRONOUS_SETTING + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_BULK_IN_ENDPOINT|(USB_SEND << 7), + USB_BULK_PIPE, + DIC_BULK_IN_ENDP_PACKET_SIZE, 0x00, + 0x00,/* This value is ignored for Bulk ENDPOINT */ + + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_BULK_OUT_ENDPOINT|(USB_RECV << 7), + USB_BULK_PIPE, + DIC_BULK_OUT_ENDP_PACKET_SIZE, 0x00, + 0x00 /* This value is ignored for Bulk ENDPOINT */ + #else + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_ISO_IN_ENDPOINT|(USB_SEND << 7), + USB_ISOCHRONOUS_PIPE, + DIC_ISO_IN_ENDP_PACKET_SIZE, 0x00, + 0x01,/* This value is for Iso ENDPOINT */ + + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_ISO_OUT_ENDPOINT|(USB_RECV << 7), + USB_ISOCHRONOUS_PIPE, + DIC_ISO_OUT_ENDP_PACKET_SIZE, 0x00, + 0x01 /* This value is for Iso ENDPOINT */ + #endif +#endif +}; + +uint_8 USB_DESC_CONST USB_STR_0[USB_STR_0_SIZE+USB_STR_DESC_SIZE] = + {sizeof(USB_STR_0), + USB_STRING_DESCRIPTOR, + 0x09, + 0x04/*equiavlent to 0x0409*/ + }; + +uint_8 USB_DESC_CONST USB_STR_1[USB_STR_1_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_1), + USB_STRING_DESCRIPTOR, +#if 0 /* << EST */ + 'F',0, + 'R',0, + 'E',0, + 'E',0, + 'S',0, + 'C',0, + 'A',0, + 'L',0, + 'E',0, + ' ',0, + 'S',0, + 'E',0, + 'M',0, + 'I',0, + 'C',0, + 'O',0, + 'N',0, + 'D',0, + 'U',0, + 'C',0, + 'T',0, + 'O',0, + 'R',0, + ' ',0, + 'I',0, + 'N',0, + 'C',0, + '.',0 +#else + 'F',0, + 'R',0, + 'E',0, + 'E',0, + 'S',0, + 'C',0, + 'A',0, + 'L',0, + 'E',0, + ' ',0, + 'I',0, + 'N',0, + 'C',0, + '.',0, +#endif + }; + + +uint_8 USB_DESC_CONST USB_STR_2[USB_STR_2_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_2), + USB_STRING_DESCRIPTOR, +#if 0 /* << EST */ + ' ',0, + ' ',0, + #ifdef __MK_xxx_H__ + 'M',0, + 'K',0, + #elif (defined __MCF52xxx_H__) + 'C',0, + 'F',0, + #elif (defined MCU_mcf51jf128) + 'J',0, + 'F',0, + #else + 'J',0, + 'M',0, + #endif + ' ',0, + 'C',0, + 'D',0, + 'C',0, + ' ',0, + 'D',0, + 'E',0, + 'M',0, + 'O',0, + ' ',0 +#else + 'F',0, + 'S',0, + 'L',0, + ' ',0, + 'C',0, + 'D',0, + 'C',0, + ' ',0, + 'D',0, + 'E',0, + 'V',0, + 'I',0, + 'C',0, + 'E',0, +#endif + }; + +/* string descriptor for serial number */ +uint_8 USB_DESC_CONST USB_STR_3[USB_STR_3_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_3), + USB_STRING_DESCRIPTOR, + '0',0, + '0',0, + '0',0, + '1',0, + '2',0, + '3',0, + 'A',0, + 'B',0, + 'C',0, + }; + +uint_8 USB_DESC_CONST USB_STR_n[USB_STR_n_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_n), + USB_STRING_DESCRIPTOR, + 'B',0, + 'A',0, + 'D',0, + ' ',0, + 'S',0, + 'T',0, + 'R',0, + 'I',0, + 'N',0, + 'G',0, + ' ',0, + 'I',0, + 'N',0, + 'D',0, + 'E',0, + 'X',0 + }; + + +USB_PACKET_SIZE const g_std_desc_size[USB_MAX_STD_DESCRIPTORS+1] = + {0, + DEVICE_DESCRIPTOR_SIZE, + CONFIG_DESC_SIZE, + 0, /* string */ + 0, /* Interface */ + 0, /* Endpoint */ + 0, /* Device Qualifier */ + 0 /* other speed config */ + }; + +uint_8_ptr const g_std_descriptors[USB_MAX_STD_DESCRIPTORS+1] = + { + NULL, + (uint_8_ptr)g_device_descriptor, + (uint_8_ptr)g_config_descriptor, + NULL, /* string */ + NULL, /* Interface */ + NULL, /* Endpoint */ + NULL, /* Device Qualifier */ + NULL /* other speed config*/ + }; + +uint_8 const g_string_desc_size[USB_MAX_STRING_DESCRIPTORS+1] = + { + sizeof(USB_STR_0), + sizeof(USB_STR_1), + sizeof(USB_STR_2), + sizeof(USB_STR_3), /* << EST serial number */ + sizeof(USB_STR_n) + }; + +uint_8_ptr const g_string_descriptors[USB_MAX_STRING_DESCRIPTORS+1] = + { + (uint_8_ptr)USB_STR_0, + (uint_8_ptr)USB_STR_1, + (uint_8_ptr)USB_STR_2, + (uint_8_ptr)USB_STR_3, /* << EST serial number */ + (uint_8_ptr)USB_STR_n + }; + +#ifdef __HC08__ /* << EST */ +#pragma MESSAGE DISABLE C4800 /* implicit cast in assignment */ +#endif +USB_ALL_LANGUAGES g_languages = { USB_STR_0, sizeof(USB_STR_0), + { + { + (uint_16)0x0409, + (const uint_8 **)g_string_descriptors, + g_string_desc_size + } + } + }; +#ifdef __HC08__ /* << EST */ +#pragma MESSAGE DEFAULT C4800 +#endif + +uint_8 const g_valid_config_values[USB_MAX_CONFIG_SUPPORTED+1]={0,1}; + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef _MC9S08JS16_H +#pragma DATA_SEG APP_DATA +#endif + +static uint_8 g_line_coding[USB_MAX_SUPPORTED_INTERFACES][LINE_CODING_SIZE] = +{ + { (LINE_CODE_DTERATE_IFACE0>> 0) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>> 8) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>>16) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>>24) & 0x000000FF, + /*e.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */ + LINE_CODE_CHARFORMAT_IFACE0, + LINE_CODE_PARITYTYPE_IFACE0, + LINE_CODE_DATABITS_IFACE0 + } +}; + +static uint_8 g_abstract_state[USB_MAX_SUPPORTED_INTERFACES][COMM_FEATURE_DATA_SIZE] = +{ + { (STATUS_ABSTRACT_STATE_IFACE0>>0) & 0x00FF, + (STATUS_ABSTRACT_STATE_IFACE0>>8) & 0x00FF + } +}; + +static uint_8 g_country_code[USB_MAX_SUPPORTED_INTERFACES][COMM_FEATURE_DATA_SIZE] = +{ + { (COUNTRY_SETTING_IFACE0>>0) & 0x00FF, + (COUNTRY_SETTING_IFACE0>>8) & 0x00FF + } +}; + +static uint_8 g_alternate_interface[USB_MAX_SUPPORTED_INTERFACES]; + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + + + /***************************************************************************** + * Local Functions - None + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Desc_Get_Descriptor + * + * @brief The function returns the correponding descriptor + * + * @param controller_ID : Controller ID + * @param type : type of descriptor requested + * @param sub_type : string index for string descriptor + * @param index : string descriptor language Id + * @param descriptor : output descriptor pointer + * @param size : size of descriptor returned + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is used to pass the pointer to the requested descriptor + *****************************************************************************/ +uint_8 USB_Desc_Get_Descriptor ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 type, /* [IN] type of descriptor requested */ + uint_8 str_num, /* [IN] string index for string descriptor */ + uint_16 index, /* [IN] string descriptor language Id */ + uint_8_ptr *descriptor, /* [OUT] output descriptor pointer */ + USB_PACKET_SIZE *size /* [OUT] size of descriptor returned */ +) +{ + UNUSED (controller_ID) + + /* string descriptors are handled saperately */ + if (type == USB_STRING_DESCRIPTOR) + { + if(index == 0) + { + /* return the string and size of all languages */ + *descriptor = (uint_8_ptr)g_languages.languages_supported_string; + *size = g_languages.languages_supported_size; + } else + { + uint_8 lang_id=0; + uint_8 lang_index=USB_MAX_LANGUAGES_SUPPORTED; + + for(;lang_id< USB_MAX_LANGUAGES_SUPPORTED;lang_id++) + { + /* check whether we have a string for this language */ + if(index == g_languages.usb_language[lang_id].language_id) + { /* check for max descriptors */ + if(str_num < USB_MAX_STRING_DESCRIPTORS) + { /* setup index for the string to be returned */ + lang_index=str_num; + } + + break; + } + + } + + /* set return val for descriptor and size */ + *descriptor = (uint_8_ptr)g_languages.usb_language[lang_id]. + lang_desc[lang_index]; + *size = g_languages.usb_language[lang_id]. + lang_desc_size[lang_index]; + } + + } + else if (type < USB_MAX_STD_DESCRIPTORS+1) + { + /* Set return val for descriptor and size */ + *descriptor = (uint_8_ptr)g_std_descriptors [type]; + + /* if there is no descriptor then return error */ + if(*descriptor == NULL) + { + return USBERR_INVALID_REQ_TYPE; + } + + *size = g_std_desc_size[type]; + } + else /* invalid descriptor */ + { + return USBERR_INVALID_REQ_TYPE; + } + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Interface + * + * @brief The function returns the alternate interface + * + * @param controller_ID : Controller Id + * @param interface : Interface number + * @param alt_interface : Output alternate interface + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is called by the framework module to get the current interface + *****************************************************************************/ +uint_8 USB_Desc_Get_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] interface number */ + uint_8_ptr alt_interface /* [OUT] output alternate interface */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get alternate interface*/ + *alt_interface = g_alternate_interface[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Interface + * + * @brief The function sets the alternate interface + * + * @param controller_ID : Controller Id + * @param interface : Interface number + * @param alt_interface : Input alternate interface + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is called by the framework module to set the interface + *****************************************************************************/ +uint_8 USB_Desc_Set_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] interface number */ + uint_8 alt_interface /* [IN] input alternate interface */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set alternate interface*/ + g_alternate_interface[interface]=alt_interface; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Valid_Configation + * + * @brief The function checks whether the configuration parameter + * input is valid or not + * + * @param controller_ID : Controller Id + * @param config_val : Configuration value + * + * @return TRUE When Valid + * FALSE When Error + ***************************************************************************** + * This function checks whether the configuration is valid or not + *****************************************************************************/ +boolean USB_Desc_Valid_Configation ( + uint_8 controller_ID,/*[IN] Controller ID */ + uint_16 config_val /*[IN] configuration value */ +) +{ + uint_8 loop_index=0; + UNUSED (controller_ID) + + /* check with only supported val right now */ + while(loop_index < (USB_MAX_CONFIG_SUPPORTED+1)) + { + if(config_val == g_valid_config_values[loop_index]) + { + return TRUE; + } + loop_index++; + } + + return FALSE; +} +/**************************************************************************//*! + * + * @name USB_Desc_Valid_Interface + * + * @brief The function checks whether the interface parameter + * input is valid or not + * + * @param controller_ID : Controller Id + * @param interface : Target interface + * + * @return TRUE When Valid + * FALSE When Error + ***************************************************************************** + * This function checks whether the interface is valid or not + *****************************************************************************/ +boolean USB_Desc_Valid_Interface ( + uint_8 controller_ID, /*[IN] Controller ID */ + uint_8 interface /*[IN] target interface */ +) +{ + uint_8 loop_index=0; + UNUSED (controller_ID) + + /* check with only supported val right now */ + while(loop_index < USB_MAX_SUPPORTED_INTERFACES) + { + if(interface == g_alternate_interface[loop_index]) + { + return TRUE; + } + loop_index++; + } + + return FALSE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Remote_Wakeup + * + * @brief The function checks whether the remote wakeup is supported or not + * + * @param controller_ID : Controller ID + * + * @return REMOTE_WAKEUP_SUPPORT (TRUE) - if remote wakeup supported + ***************************************************************************** + * This function returns remote wakeup is supported or not + *****************************************************************************/ +boolean USB_Desc_Remote_Wakeup ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return REMOTE_WAKEUP_SUPPORT; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Endpoints + * + * @brief The function returns with the list of all non control endpoints used + * + * @param controller_ID : Controller ID + * + * @return pointer to USB_ENDPOINTS + ***************************************************************************** + * This function returns the information about all the non control endpoints + * implemented + *****************************************************************************/ +void* USB_Desc_Get_Endpoints ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return (void*)&usb_desc_ep; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Line_Coding + * + * @brief The function returns the Line Coding/Configuraion + * + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param coding_data : Output line coding data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns current Line Coding Parameters + *****************************************************************************/ +uint_8 USB_Desc_Get_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *coding_data /* [OUT] Line Coding Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *coding_data = g_line_coding[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Line_Coding + * + * @brief The function sets the Line Coding/Configuraion + * + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param coding_data : Output line coding data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets Line Coding Structure with the HOST specified values + *****************************************************************************/ +uint_8 USB_Desc_Set_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *coding_data /* [IN] Line Coding Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set line coding data*/ + for (count = 0; count < LINE_CODING_SIZE; count++) + { + g_line_coding[interface][count] = *((*coding_data + + USB_SETUP_PKT_SIZE) + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Abstract_State + * + * @brief The function gets the current setting for communication feature + * (ABSTRACT_STATE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns ABSTRACT STATE Communication Feature to the Host + *****************************************************************************/ +uint_8 USB_Desc_Get_Abstract_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *feature_data = g_abstract_state[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Country_Setting + * + * @brief The function gets the current setting for communication feature + * (COUNTRY_CODE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns the country Code to the Host + *****************************************************************************/ +uint_8 USB_Desc_Get_Country_Setting ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *feature_data = g_country_code[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Abstract_State + * + * @brief The function gets the current setting for communication feature + * (ABSTRACT_STATE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets the ABSTRACT State specified by the Host + *****************************************************************************/ +uint_8 USB_Desc_Set_Abstract_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set Abstract State Feature*/ + for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) + { + g_abstract_state[interface][count] = *(*feature_data + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Country_Setting + * + * @brief The function gets the current setting for communication feature + * (COUNTRY_CODE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets the country code specified by the HOST + *****************************************************************************/ +uint_8 USB_Desc_Set_Country_Setting( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) + { + g_country_code[interface][count] = *(*feature_data + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.h new file mode 100644 index 0000000..ddabd3d --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_descriptor.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_descriptor.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file is a header file for USB Descriptors required for Virtual + * COM Loopback Application + *****************************************************************************/ + +#ifndef _USB_DESCRIPTOR_H +#define _USB_DESCRIPTOR_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_class.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define REMOTE_WAKEUP_SUPPORT (FALSE) +#define DATA_CLASS_SUPPORT (TRUE) +#define CIC_NOTIF_ELEM_SUPPORT (TRUE) /* Mandatory */ +#define DIC_ISOCHRONOUS_SETTING (FALSE) + +#define IMPLEMENT_QUEUING (TRUE) + +/* Communication Class SubClass Codes */ +#define DIRECT_LINE_CONTROL_MODEL (0x01) +#define ABSTRACT_CONTROL_MODEL (0x02) +#define TELEPHONE_CONTROL_MODEL (0x03) +#define MULTI_CHANNEL_CONTROL_MODEL (0x04) +#define CAPI_CONTROL_MOPDEL (0x05) +#define ETHERNET_NETWORKING_CONTROL_MODEL (0x06) +#define ATM_NETWORKING_CONTROL_MODEL (0x07) +#define WIRELESS_HANDSET_CONTROL_MODEL (0x08) +#define DEVICE_MANAGEMENT (0x09) +#define MOBILE_DIRECT_LINE_MODEL (0x0A) +#define OBEX (0x0B) +#define ETHERNET_EMULATION_MODEL (0x0C) + +/* Communication Class Protocol Codes */ +#define NO_CLASS_SPECIFIC_PROTOCOL (0x00) +#define AT_250_PROTOCOL (0x01) +#define AT_PCCA_101_PROTOCOL (0x02) +#define AT_PCCA_101_ANNEX_O (0x03) +#define AT_GSM_7_07 (0x04) +#define AT_3GPP_27_007 (0x05) +#define AT_TIA_CDMA (0x06) +#define ETHERNET_EMULATION_PROTOCOL (0x07) +#define EXTERNAL_PROTOCOL (0xFE) +#define VENDOR_SPECIFIC (0xFF) + +/* Data Class Protocol Codes */ +/* #define NO_CLASS_SPECIFIC_PROTOCOL (0x00) */ +#define PYHSICAL_INTERFACE_PROTOCOL (0x30) +#define HDLC_PROTOCOL (0x31) +#define TRANSPARENT_PROTOCOL (0x32) +#define MANAGEMENT_PROTOCOL (0x50) +#define DATA_LINK_Q931_PROTOCOL (0x51) +#define DATA_LINK_Q921_PROTOCOL (0x52) +#define DATA_COMPRESSION_V42BIS (0x90) +#define EURO_ISDN_PROTOCOL (0x91) +#define RATE_ADAPTION_ISDN_V24 (0x92) +#define CAPI_COMMANDS (0x93) +#define HOST_BASED_DRIVER (0xFD) +#define CDC_UNIT_FUNCTIONAL (0xFE) +/* #define VENDOR_SPECIFIC (0xFF) */ + +/* Descriptor SubType in Communications Class Functional Descriptors */ +#define HEADER_FUNC_DESC (0x00) +#define CALL_MANAGEMENT_FUNC_DESC (0x01) +#define ABSTRACT_CONTROL_FUNC_DESC (0x02) +#define DIRECT_LINE_FUNC_DESC (0x03) +#define TELEPHONE_RINGER_FUNC_DESC (0x04) +#define TELEPHONE_REPORT_FUNC_DESC (0x05) +#define UNION_FUNC_DESC (0x06) +#define COUNTRY_SELECT_FUNC_DESC (0x07) +#define TELEPHONE_MODES_FUNC_DESC (0x08) +#define USB_TERMINAL_FUNC_DESC (0x09) +#define NETWORK_CHANNEL_FUNC_DESC (0x0A) +#define PROTOCOL_UNIT_FUNC_DESC (0x0B) +#define EXTENSION_UNIT_FUNC_DESC (0x0C) +#define MULTI_CHANNEL_FUNC_DESC (0x0D) +#define CAPI_CONTROL_FUNC_DESC (0x0E) +#define ETHERNET_NETWORKING_FUNC_DESC (0x0F) +#define ATM_NETWORKING_FUNC_DESC (0x10) +#define WIRELESS_CONTROL_FUNC_DESC (0x11) +#define MOBILE_DIRECT_LINE_FUNC_DESC (0x12) +#define MDLM_DETAIL_FUNC_DESC (0x13) +#define DEVICE_MANAGEMENT_FUNC_DESC (0x14) +#define OBEX_FUNC_DESC (0x15) +#define COMMAND_SET_FUNC_DESC (0x16) +#define COMMAND_SET_DETAIL_FUNC_DESC (0x17) +#define TELEPHONE_CONTROL_FUNC_DESC (0x18) +#define OBEX_SERVICE_ID_FUNC_DESC (0x19) + + +#define CIC_SUBCLASS_CODE ABSTRACT_CONTROL_MODEL +#define CIC_PROTOCOL_CODE NO_CLASS_SPECIFIC_PROTOCOL +#define DIC_PROTOCOL_CODE NO_CLASS_SPECIFIC_PROTOCOL +#define CIC_ENDP_COUNT (0+(CIC_NOTIF_ELEM_SUPPORT & 0x01) * 1) +#define DIC_ENDP_COUNT (2) + +#define CIC_NOTIF_ENDPOINT (3) +#define CIC_NOTIF_ENDP_PACKET_SIZE (16) +#define DIC_BULK_IN_ENDPOINT (1) +#define DIC_BULK_IN_ENDP_PACKET_SIZE (16)/* max supported is 64 */ +#define DIC_BULK_OUT_ENDPOINT (2) +#define DIC_BULK_OUT_ENDP_PACKET_SIZE (16)/* max supported is 64*/ + +#if DIC_ISOCHRONOUS_SETTING +#define DIC_ISO_IN_ENDPOINT (1) +#define DIC_ISO_IN_ENDP_PACKET_SIZE (64) +#define DIC_ISO_OUT_ENDPOINT (2) +#define DIC_ISO_OUT_ENDP_PACKET_SIZE (64) +#endif +#define REMOTE_WAKEUP_SHIFT (5) + +/* Various descriptor sizes */ +#define DEVICE_DESCRIPTOR_SIZE (18) +#define CONFIG_ONLY_DESC_SIZE (9) +#define CONFIG_DESC_SIZE (CONFIG_ONLY_DESC_SIZE + 28 + \ + (CIC_NOTIF_ELEM_SUPPORT & 0x01) \ + * 7 + DATA_CLASS_SUPPORT * 23) +#define DEVICE_QUALIFIER_DESCRIPTOR_SIZE (10) +#define IFACE_ONLY_DESC_SIZE (9) +#define ENDP_ONLY_DESC_SIZE (7) + +/* Max descriptors provided by the Application */ +#define USB_MAX_STD_DESCRIPTORS (7) + +/* Max configuration supported by the Application */ +#define USB_MAX_CONFIG_SUPPORTED (1) + +/* Max string descriptors supported by the Application */ +#define USB_MAX_STRING_DESCRIPTORS (4) /* << EST added one more for serial number */ + +/* Max language codes supported by the USB */ +#define USB_MAX_LANGUAGES_SUPPORTED (1) + +/* string descriptors sizes */ +#define USB_STR_DESC_SIZE (2) +#define USB_STR_0_SIZE (2) +#define USB_STR_1_SIZE (2*14) /* bus reported vendor string */ +#define USB_STR_2_SIZE (2*14) /* bus reported device description string */ +#define USB_STR_3_SIZE (2*9) /* serial number descriptor string */ +#define USB_STR_n_SIZE (32) + +/* descriptors codes */ +#define USB_DEVICE_DESCRIPTOR (1) +#define USB_CONFIG_DESCRIPTOR (2) +#define USB_STRING_DESCRIPTOR (3) +#define USB_IFACE_DESCRIPTOR (4) +#define USB_ENDPOINT_DESCRIPTOR (5) +#define USB_DEVQUAL_DESCRIPTOR (6) +#define USB_CS_INTERFACE (0x24) +#define USB_CS_ENDPOINT (0x25) + +#define USB_MAX_SUPPORTED_INTERFACES (2) + +/* Implementation Specific Macros */ +#define LINE_CODING_SIZE (0x07) +#define COMM_FEATURE_DATA_SIZE (0x02) + +#define LINE_CODE_DTERATE_IFACE0 (115200) /*e.g 9600 is 0x00002580 */ +#define LINE_CODE_CHARFORMAT_IFACE0 (0x00) /* 1 stop bit */ +#define LINE_CODE_PARITYTYPE_IFACE0 (0x00) /* No Parity */ +#define LINE_CODE_DATABITS_IFACE0 (0x08) /* Data Bits Format */ + +#define LINE_CODE_DTERATE_IFACE1 (9600) /*e.g. 115200 is 0x0001C200*/ +#define LINE_CODE_CHARFORMAT_IFACE1 (0x00) /* 1 stop bit */ +#define LINE_CODE_PARITYTYPE_IFACE1 (0x00) /* No Parity */ +#define LINE_CODE_DATABITS_IFACE1 (0x08) /* Data Bits Format */ + +#define STATUS_ABSTRACT_STATE_IFACE0 (0x0000) /* Disable Multiplexing + ENDP in this interface will + continue to accept/offer data*/ +#define STATUS_ABSTRACT_STATE_IFACE1 (0x0000) /* Disable Multiplexing + ENDP in this interface will + continue to accept/offer data*/ +#define COUNTRY_SETTING_IFACE0 (0x0000) /* Country Code in the format as + defined in [ISO3166] */ +#define COUNTRY_SETTING_IFACE1 (0x0000) /* Country Code in the format as + defined in [ISO3166] */ + +/* Notifications Support */ +#define PSTN_SUBCLASS_NOTIF_SUPPORT (TRUE) +#define WMC_SUBCLASS_NOTIF_SUPPORT (FALSE) +#define CDC_CLASS_NOTIF_SUPPORT (FALSE) + +#define CDC_DESC_ENDPOINT_COUNT (CIC_ENDP_COUNT+(DATA_CLASS_SUPPORT & 0x01) \ + *DIC_ENDP_COUNT) + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef const struct _USB_LANGUAGE +{ + uint_16 const language_id; /* Language ID */ + uint_8 const ** lang_desc; /* Language Descriptor String */ + uint_8 const * lang_desc_size; /* Language Descriptor Size */ +} USB_LANGUAGE; + +typedef const struct _USB_ALL_LANGUAGES +{ + /* Pointer to Supported Language String */ + uint_8 const *languages_supported_string; + /* Size of Supported Language String */ + uint_8 const languages_supported_size; + /* Array of Supported Languages */ + USB_LANGUAGE usb_language[USB_MAX_SUPPORTED_INTERFACES]; +}USB_ALL_LANGUAGES; + +typedef const struct _USB_ENDPOINTS +{ + /* Number of non control Endpoints */ + uint_8 count; + /* Array of Endpoints Structures */ + USB_EP_STRUCT ep[CDC_DESC_ENDPOINT_COUNT]; +}USB_ENDPOINTS; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Desc_Get_Descriptor( + uint_8 controller_ID, + uint_8 type, + uint_8 str_num, + uint_16 index, + uint_8_ptr *descriptor, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Desc_Get_Interface( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr alt_interface); + + +extern uint_8 USB_Desc_Set_Interface( + uint_8 controller_ID, + uint_8 interface, + uint_8 alt_interface); + +extern boolean USB_Desc_Valid_Configation( + uint_8 controller_ID, + uint_16 config_val); + +extern boolean USB_Desc_Valid_Interface( + uint_8 controller_ID, + uint_8 interface); + +extern boolean USB_Desc_Remote_Wakeup(uint_8 controller_ID); + +extern void* USB_Desc_Get_Endpoints(uint_8 controller_ID); + +extern uint_8 USB_Desc_Get_Line_Coding( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *coding_data); + +extern uint_8 USB_Desc_Set_Line_Coding( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *coding_data); + +extern uint_8 USB_Desc_Get_Abstract_State( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Get_Country_Setting( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Set_Abstract_State( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Set_Country_Setting( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); + +#endif + + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_devapi.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_devapi.h new file mode 100644 index 0000000..7c207fc --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_devapi.h @@ -0,0 +1,479 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_devapi.h + * + * @author + * + * @version + * + * @date + * + * @brief This file contains S08 USB stack device layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_DEVAPI_H +#define _USB_DEVAPI_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" /* User Defined Data Types */ +#include "hidef.h" /* for EnableInterrupts macro */ +#include "derivative.h" /* include peripheral declarations */ +#include "usb_user_config.h" /* User Configuration File << EST 'user_config.h' conflicts with MQX Lite */ +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H +#define USB_MAX_EP_BUFFER_SIZE (512) +#else +#define USB_MAX_EP_BUFFER_SIZE (255) +#endif +#else +/* device is Kinetis K20D50 << EST */ +#define USB_MAX_EP_BUFFER_SIZE (512) +#endif +#ifndef CONTROL_ENDPOINT +#define CONTROL_ENDPOINT (0) +#endif + +#define USB_SETUP_PKT_SIZE (8) /* Setup Packet Size */ + +/* Error codes */ +#define USB_OK (0x00) +#define USBERR_ALLOC (0x81) +#define USBERR_BAD_STATUS (0x82) +#define USBERR_CLOSED_SERVICE (0x83) +#define USBERR_OPEN_SERVICE (0x84) +#define USBERR_TRANSFER_IN_PROGRESS (0x85) +#define USBERR_ENDPOINT_STALLED (0x86) +#define USBERR_ALLOC_STATE (0x87) +#define USBERR_DRIVER_INSTALL_FAILED (0x88) +#define USBERR_DRIVER_NOT_INSTALLED (0x89) +#define USBERR_INSTALL_ISR (0x8A) +#define USBERR_INVALID_DEVICE_NUM (0x8B) +#define USBERR_ALLOC_SERVICE (0x8C) +#define USBERR_INIT_FAILED (0x8D) +#define USBERR_SHUTDOWN (0x8E) +#define USBERR_INVALID_PIPE_HANDLE (0x8F) +#define USBERR_OPEN_PIPE_FAILED (0x90) +#define USBERR_INIT_DATA (0x91) +#define USBERR_SRP_REQ_INVALID_STATE (0x92) +#define USBERR_TX_FAILED (0x93) +#define USBERR_RX_FAILED (0x94) +#define USBERR_EP_INIT_FAILED (0x95) +#define USBERR_EP_DEINIT_FAILED (0x96) +#define USBERR_TR_FAILED (0x97) +#define USBERR_BANDWIDTH_ALLOC_FAILED (0x98) +#define USBERR_INVALID_NUM_OF_ENDPOINTS (0x99) +#define USBERR_NOT_SUPPORTED (0x9A) + +#define USBERR_DEVICE_NOT_FOUND (0xC0) +#define USBERR_DEVICE_BUSY (0xC1) +#define USBERR_NO_DEVICE_CLASS (0xC3) +#define USBERR_UNKNOWN_ERROR (0xC4) +#define USBERR_INVALID_BMREQ_TYPE (0xC5) +#define USBERR_GET_MEMORY_FAILED (0xC6) +#define USBERR_INVALID_MEM_TYPE (0xC7) +#define USBERR_NO_DESCRIPTOR (0xC8) +#define USBERR_NULL_CALLBACK (0xC9) +#define USBERR_NO_INTERFACE (0xCA) +#define USBERR_INVALID_CFIG_NUM (0xCB) +#define USBERR_INVALID_ANCHOR (0xCC) +#define USBERR_INVALID_REQ_TYPE (0xCD) + +/* Pipe Types */ +#define USB_CONTROL_PIPE (0x00) +#define USB_ISOCHRONOUS_PIPE (0x01) +#define USB_BULK_PIPE (0x02) +#define USB_INTERRUPT_PIPE (0x03) + +/* Device States */ +#define USB_STATE_UNKNOWN (0xff) +#define USB_STATE_PENDING_ADDRESS (0x04) +#define USB_STATE_POWERED (0x03) +#define USB_STATE_DEFAULT (0x02) +#define USB_STATE_ADDRESS (0x01) +#define USB_STATE_CONFIG (0x00) +#define USB_STATE_SUSPEND (0x80) + +/* Get_Status Request information for DEVICE */ +#define USB_SELF_POWERED (0x01) +#define USB_REMOTE_WAKEUP (0x02) + +/* Get_Status Request information for OTG (WINDEX = 0xF000) */ +#ifdef OTG_BUILD +#define USB_OTG_HOST_REQUEST_FLAG (0x01) +#endif + +/* Bus Control values */ +#define USB_NO_OPERATION (0x00) +#define USB_ASSERT_BUS_RESET (0x01) +#define USB_DEASSERT_BUS_RESET (0x02) +#define USB_ASSERT_RESUME (0x03) +#define USB_DEASSERT_RESUME (0x04) +#define USB_SUSPEND_SOF (0x05) +#define USB_RESUME_SOF (0x06) + +/* possible values of Status */ +#define USB_STATUS_IDLE (0) +#define USB_STATUS_TRANSFER_ACCEPTED (6) +#define USB_STATUS_TRANSFER_PENDING (2) +#define USB_STATUS_TRANSFER_IN_PROGRESS (3) +#define USB_STATUS_ERROR (4) +#define USB_STATUS_DISABLED (5) +#define USB_STATUS_STALLED (1) +#define USB_STATUS_TRANSFER_QUEUED (7) + +#define USB_STATUS_UNKNOWN (0xFF) + +#define USB_CONTROL_ENDPOINT (0) + +#define USB_RECV (0) +#define USB_SEND (1) + +#define USB_DEVICE_DONT_ZERO_TERMINATE (0x1) + +#define USB_SETUP_DATA_XFER_DIRECTION (0x80) + +#define USB_SPEED_FULL (0) +#define USB_SPEED_LOW (1) +#define USB_SPEED_HIGH (2) + +#define USB_MAX_PKTS_PER_UFRAME (0x6) + +#define USB_TEST_MODE_TEST_PACKET (0x0400) + +/* Available service types */ +/* Services 0 through 15 are reserved for endpoints */ +#define USB_SERVICE_EP0 (0x00) +#define USB_SERVICE_EP1 (0x01) +#define USB_SERVICE_EP2 (0x02) +#define USB_SERVICE_EP3 (0x03) +#define USB_SERVICE_EP4 (0x04) +#define USB_SERVICE_EP5 (0x05) +#define USB_SERVICE_EP6 (0x06) +#define USB_SERVICE_EP7 (0x07) +#define USB_SERVICE_EP8 (0x08) +#define USB_SERVICE_EP9 (0x09) +#define USB_SERVICE_EP10 (0x0a) +#define USB_SERVICE_EP11 (0x0b) +#define USB_SERVICE_EP12 (0x0c) +#define USB_SERVICE_EP13 (0x0d) +#define USB_SERVICE_EP14 (0x0e) +#define USB_SERVICE_EP15 (0x0f) + +#define USB_SERVICE_BUS_RESET (0x10) +#define USB_SERVICE_SUSPEND (0x11) +#define USB_SERVICE_SOF (0x12) +#define USB_SERVICE_RESUME (0x13) +#define USB_SERVICE_SLEEP (0x14) +#define USB_SERVICE_SPEED_DETECTION (0x15) +#define USB_SERVICE_ERROR (0x16) +#define USB_SERVICE_STALL (0x17) +#define USB_SERVICE_MAX (0x18) + +#if 0 /* << EST */ +#if (defined(_MCF51JM128_H) ||defined(_MCF51MM256_H) || (defined _MCF51JE256_H)) + #define USB_SERVICE_MAX_EP USB_SERVICE_EP15 +#else + #ifdef DOUBLE_BUFFERING_USED + #define USB_SERVICE_MAX_EP USB_SERVICE_EP6 + #else + #define USB_SERVICE_MAX_EP USB_SERVICE_EP4 + #endif +#endif +#else +/* device is Kinetis K20D50 << EST */ +#ifdef DOUBLE_BUFFERING_USED + #define USB_SERVICE_MAX_EP USB_SERVICE_EP6 +#else + #define USB_SERVICE_MAX_EP USB_SERVICE_EP4 +#endif +#endif + +/* Informational Request/Set Types */ +/* component parameter in USB_Device_Get/Set_Status */ +#define USB_COMPONENT_DIRECTION_SHIFT (7) +#define USB_COMPONENT_DIRECTION_MASK (0x01) +#define USB_STATUS_DEVICE_STATE (0x01) +#define USB_STATUS_INTERFACE (0x02) +#define USB_STATUS_ADDRESS (0x03) +#define USB_STATUS_CURRENT_CONFIG (0x04) +#define USB_STATUS_SOF_COUNT (0x05) +#define USB_STATUS_DEVICE (0x06) + +// Endpoint attributes +#define EP_TRANSFER_TYPE_CONTROL (0x0<<0) +#define EP_TRANSFER_TYPE_ISOCHRONOUS (0x1<<0) +#define EP_TRANSFER_TYPE_BULK (0x2<<0) +#define EP_TRANSFER_TYPE_INTERRUPT (0x3<<0) + +/* Standard Request Code */ +#define GET_STATUS 0x0 +#define CLEAR_FEATURE 0x1 +#define SET_FEATURE 0x3 +#define SET_ADDRESS 0x5 +#define GET_DESCRIPTOR 0x6 +#define SET_DESCRIPTOR 0x7 +#define GET_CONFIGURATION 0x8 +#define SET_CONFIGURATION 0x9 +#define GET_INTERFACE 0xA +#define SET_INTERFACE 0xB +#define SYNCH_FRAME 0xC + +#ifdef OTG_BUILD + #define USB_STATUS_OTG (0x07) + #define USB_STATUS_TEST_MODE (0x08) +#else + #define USB_STATUS_TEST_MODE (0x07) +#endif + +#define USB_STATUS_ENDPOINT (0x10) +#define USB_STATUS_ENDPOINT_NUMBER_MASK (0x0F) + +#define UNINITIALISED_VAL (0xffffffff) + +#if 0 /* << EST */ +#if (defined MCU_MK40N512VMD100) || (defined MCU_MK53N512CMD100) || (defined MCU_MK60N512VMD100) || (defined MCU_MK70F12) + #define USB_DEVICE_ASSERT_RESUME() USB0_CTL |= USB_CTL_RESUME_MASK; + #define USB_DEVICE_DEASSERT_RESUME() USB0_CTL &= ~USB_CTL_RESUME_MASK; +#elif (defined _MC9S08JE128_H) || (defined _MC9S08JM16_H) || defined(_MC9S08JM60_H) || (defined _MC9S08JS16_H) || (defined _MC9S08MM128_H) + #define USB_DEVICE_ASSERT_RESUME() CTL_CRESUME = 1; + #define USB_DEVICE_DEASSERT_RESUME() CTL_CRESUME = 0; +#elif (defined _MCF51JE256_H) || (defined MCU_mcf51jf128) || defined(_MCF51MM256_H) + #define USB_DEVICE_ASSERT_RESUME() USBTRC0_USBRESMEN = 1; + #define USB_DEVICE_DEASSERT_RESUME() USBTRC0_USBRESMEN = 0; +#elif (defined __MCF52221_H__) || defined(__MCF52259_H__) + #define USB_DEVICE_ASSERT_RESUME() CTL |= MCF_USB_OTG_CTL_RESUME; + #define USB_DEVICE_DEASSERT_RESUME() CTL &= ~MCF_USB_OTG_CTL_RESUME; +#endif +#else +/* device is Kinetis K20D50 << EST */ +#endif + +#define USB_PROCESS_PENDING() ((gu8ProcessPendingFlag != 0) || (gtUSBEPEventFlags != 0)) + + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef void _PTR_ _usb_device_handle; +typedef uint_8 T_EP_BITFIELD; + +#if 0 /* << EST */ +#if !(defined _MC9S08JE128_H) && !(defined _MC9S08JM16_H) && !defined(_MC9S08JM60_H) && !(defined _MC9S08JS16_H) && !(defined _MC9S08MM128_H) +#pragma pack (1) /* Enforce 1 byte struct alignment */ +#endif +#else +#ifndef __HIWARE__ +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) /* Enforce 1 byte struct alignment */ +#endif +#endif + +#ifdef __MK_xxx_H__ + #if (defined(__CWCC__) || defined(__GNUC__)) + #define ALIGN __attribute__ ((packed)) + #elif((defined __IAR_SYSTEMS_ICC__) || (defined __CC_ARM)) + #define ALIGN + #else + #define ALIGN + #endif +#else + #define ALIGN +#endif + +typedef struct _USB_DEV_EVENT_STRUCT +{ + uint_8 controller_ID; /* controller ID */ + uint_8 ep_num; + boolean setup; /* is setup packet */ + boolean direction; /* direction of endpoint */ + uint_8* buffer_ptr; /* pointer to buffer */ + uint_8 errors; /* Any errors */ + USB_PACKET_SIZE len; /* buffer size of endpoint */ +}ALIGN USB_DEV_EVENT_STRUCT, *PTR_USB_DEV_EVENT_STRUCT; + +// Same endpoint can have multiple function assignments in g_usb_CB, depending on user input +#ifndef MULTIPLE_DEVICES + typedef void(_CODE_PTR_ const USB_SERVICE_CALLBACK)(PTR_USB_DEV_EVENT_STRUCT); +#else + typedef void(_CODE_PTR_ USB_SERVICE_CALLBACK)(PTR_USB_DEV_EVENT_STRUCT); +#endif + +typedef struct _USB_EP_STRUCT +{ + uint_8 ep_num; /* endpoint number */ + uint_8 type; /* type of endpoint */ + uint_8 direction; /* direction of endpoint */ + USB_PACKET_SIZE size ALIGN; /* buffer size of endpoint */ +}ALIGN USB_EP_STRUCT, *USB_EP_STRUCT_PTR; + +#if (defined(__CWCC__))/*||defined(__GNUC__))*/ /* << EST: that pragma does not exist for gcc */ + #pragma options align = reset +#elif defined(__GNUC__) /* << EST */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__CC_ARM) + #pragma pack() +#endif + + +extern volatile uint_8 gu8ProcessPendingFlag; +extern volatile T_EP_BITFIELD gtUSBEPEventFlags; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 _usb_device_init ( + uint_8 device_number, + _usb_device_handle _PTR_ handle, + uint_8 number_of_endpoints, + uint_8 bVregEn +); + +extern uint_8 _usb_device_deinit(void); + +extern uint_8 _usb_device_init_endpoint( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_16 max_packet_size, + uint_8 direction, + uint_8 endpoint_type, + uint_8 flag +); + +extern uint_8 _usb_device_cancel_transfer ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern uint_8 _usb_device_deinit_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern uint_8 _usb_device_recv_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uchar_ptr buffer_ptr, + uint_32 size +); + +extern uint_8 _usb_device_send_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uchar_ptr buffer_ptr, + uint_32 size +); + +extern uint_8 _usb_device_get_send_buffer ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8_ptr *buff_ptr, /* [OUT] Buffer for IN endpoint */ + USB_PACKET_SIZE *size /* [OUT] Size of IN endpoint */ +); + +extern void _usb_device_shutdown ( + _usb_device_handle handle +); + +extern void _usb_device_stall_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_unstall_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_read_setup_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8_ptr buffer_ptr +); + +extern uint_8 _usb_device_get_status ( + _usb_device_handle handle, + uint_8 component, + uint_8_ptr status +); + +extern uint_8 _usb_device_set_status ( + _usb_device_handle handle, + uint_8 component, + uint_8 setting +); + +extern void _usb_device_clear_data0_endpoint( + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_assert_resume ( + _usb_device_handle handle +); + +extern uint_8 _usb_device_register_service ( + uint_8 controller_ID, + uint_8 type, + USB_SERVICE_CALLBACK service +); + +extern uint_8 _usb_device_unregister_service ( + _usb_device_handle handle, + uint_8 event_endpoint +); + +extern uint_8 _usb_device_get_transfer_status ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_set_address ( + _usb_device_handle handle, + uint_8 address +); + +extern uint_8 USB_Device_Call_Service( + uint_8 type, + PTR_USB_DEV_EVENT_STRUCT event +); + +extern void USB_Engine(void); + +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_driver.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_driver.c new file mode 100644 index 0000000..2f0198b --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_driver.c @@ -0,0 +1,636 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_driver.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains S08 USB stack device layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_devapi.h" /* USB Device Layer API Header File */ +#include "usb_dciapi.h" /* USB Controller API Header File */ +#ifdef _MK_xxx_H_ + #include "usb_dci_kinetis.h" +#endif +#ifndef MULTIPLE_DEVICES + #include "USB_Config.h" +#endif + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +extern void USB_Control_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Reset_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Sof_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Resume_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Suspend_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Error_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Stall_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event); + +/* Array of USB Service pointers */ +#ifdef MULTIPLE_DEVICES + static USB_SERVICE_CALLBACK g_usb_CB[USB_SERVICE_MAX]; +#else + static USB_SERVICE_CALLBACK g_usb_CB[USB_SERVICE_MAX] = { + USB_EP0_CALLBACK, + USB_EP1_CALLBACK, + USB_EP2_CALLBACK, + USB_EP3_CALLBACK, + USB_EP4_CALLBACK, + USB_EP5_CALLBACK, + USB_EP6_CALLBACK, + USB_EP7_CALLBACK, + USB_EP8_CALLBACK, + USB_EP9_CALLBACK, + USB_EP10_CALLBACK, + USB_EP11_CALLBACK, + USB_EP12_CALLBACK, + USB_EP13_CALLBACK, + USB_EP14_CALLBACK, + USB_EP15_CALLBACK, + USB_BUS_RESET_CALLBACK, + USB_SUSPEND_CALLBACK, + USB_SOF_CALLBACK, + USB_RESUME_CALLBACK, + USB_SLEEP_CALLBACK, + USB_SPEED_DETECTION_CALLBACK, + USB_ERROR_CALLBACK, + USB_STALL_CALLBACK +}; +#endif +/* Array of USB Component Status */ +/* Test mode is the last service */ +static uint_8 g_usb_component_status[USB_STATUS_TEST_MODE]; +/* Array of USB Endpoint Status */ +static uint_8 g_usb_ep_status[MAX_SUPPORTED_ENDPOINTS]; +/* Current un-initialized non CONTROL Endpoint */ +static uint_8 g_EPn=0; +/* Maximum number of Non CONTROL Endpoint required by upper layer */ +static uint_8 g_EPn_max=0; + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes - None + *****************************************************************************/ +static void USB_Device_Init_Params(void); + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K20D50 << EST */ +#endif +/***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_DCI_Init ( + uint_8 controller_ID, + uint_8 bVregEn +); +extern uint_8 USB_DCI_DeInit(void); + +/**************************************************************************//*! + * + * @name USB_Device_Init_Params + * + * @brief The function initializes the Device Layer Structures + * + * @param None + * + * @return None + * + ****************************************************************************** + * Initializes USB Device Layer Structures + *****************************************************************************/ +static void USB_Device_Init_Params(void) +{ + uint_8 loop_index=0; + + g_EPn= g_EPn_max; /* 1 control endpoint */ + + /* + Initialize USB_STATUS_DEVICE_STATE, USB_STATUS_INTERFACE, + USB_STATUS_ADDRESS, USB_STATUS_CURRENT_CONFIG, USB_STATUS_SOF_COUNT + and USB_STATUS_DEVICE to USB_STATUS_UNKNOWN + */ + for(loop_index = 0; loop_index < USB_STATUS_TEST_MODE; loop_index++) + { + #ifdef OTG_BUILD + if(loop_index != (USB_STATUS_OTG-1)) /* Do not initialize the OTG status with 0xFFFF */ + #endif + { + g_usb_component_status[loop_index] = USB_STATUS_UNKNOWN; + } + } + + /* Initialize status of All Endpoints to USB_STATUS_DISABLED */ + for(loop_index = 0; loop_index < MAX_SUPPORTED_ENDPOINTS; loop_index++) + { + g_usb_ep_status[loop_index] = USB_STATUS_DISABLED; + } +} + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + + +/**************************************************************************//*! + * + * @name _usb_device_init + * + * @brief The function initializes the Device and Controller layer + * + * @param device_number : USB Device controller to initialize + * @param handle : pointer to USB Device handle + * @param number_of_endpoints : Endpoint count of the application + * + * @return status + * USB_OK : When Successfull + * USBERR_INVALID_NUM_OF_ENDPOINTS : When endpoints > max Supported + ****************************************************************************** + * This function initializes the Device layer and the Controller layer of the + * S08 USB stack. It initializes the variables used for this layer and then + * calls the controller layer initialize function + *****************************************************************************/ +uint_8 _usb_device_init ( + uint_8 device_number, /* [IN] USB Device controller to initialize */ + _usb_device_handle _PTR_ handle, /* [IN] Pointer to USB Device handle */ + uint_8 number_of_endpoints, /* [IN] Number of endpoints to initialize */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ + UNUSED(handle); + + /* validate endpoints param */ + if((number_of_endpoints > MAX_SUPPORTED_ENDPOINTS) || + (number_of_endpoints < MIN_SUPPORTED_ENDPOINTS)) + { + return USBERR_INVALID_NUM_OF_ENDPOINTS; + } + + /* init variables */ + g_EPn_max = (uint_8)(number_of_endpoints - 1); + + USB_Device_Init_Params(); + +#ifdef MULTIPLE_DEVICES + /* Initialize all services to null value */ + Clear_Mem((uint_8_ptr)g_usb_CB, + (uint_32)(sizeof(USB_SERVICE_CALLBACK) * USB_SERVICE_MAX), (uint_8)0); +#endif + /* Call controller layer initialization function */ + return USB_DCI_Init(device_number, bVregEn); + +} + +/**************************************************************************//*! + * + * @name _usb_device_deinit + * + * @brief The function de-initializes the Device and Controller layer + * + * @return status + * USB_OK : When Successfull + * USBERR_INVALID_NUM_OF_ENDPOINTS : When endpoints > max Supported + ****************************************************************************** + * This function de-initializes the Device layer and the Controller layer + *****************************************************************************/ +uint_8 _usb_device_deinit(void) +{ + g_EPn_max = 0; + /* Call controller layer de-initialization function */ + return USB_DCI_DeInit(); +} + +/**************************************************************************//*! + * + * @name _usb_device_init_endpoint + * + * @brief The function initializes the endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param max_packet_size : Maximum packet size (in bytes) for the endpoint + * @param direction : Direction of transfer + * @param endpoint_type : Type of endpoint + * @param flag : Zero termination flag + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_INIT_FAILED : When endpoints > max Supported + ****************************************************************************** + * + * This function initializes an endpoint the Device layer and the Controller + * layer in the S08 USB stack. It validate whether all endpoints have already + * been initialized or not and then calls the controller layer endpoint + * initialize function + * + *****************************************************************************/ +uint_8 _usb_device_init_endpoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number*/ + uint_16 max_packet_size, /* [IN] Maximum packet size (in bytes) for the endpoint */ + uint_8 direction, /* [IN] Direction of transfer */ + uint_8 endpoint_type, /* [IN] Type of endpoint */ + uint_8 flag /* [IN] Zero termination flag */ +) +{ + USB_EP_STRUCT ep_str; + + uint_8 status = USB_OK; + + /* check if all endpoint have already been initialised */ + if((g_EPn == 0) && (endpoint_number != CONTROL_ENDPOINT)) + { + return USBERR_EP_INIT_FAILED; + } + + ep_str.direction = direction; + ep_str.ep_num = endpoint_number; + +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H + ep_str.size = max_packet_size; +#else + ep_str.size = (char)max_packet_size; +#endif +#else +/* device is Kinetis K20D50 << EST */ + ep_str.size = max_packet_size; +#endif + + ep_str.type = endpoint_type; + + /* call controller layer for initiazation */ + status = USB_DCI_Init_EndPoint(*((uint_8*)handle), &ep_str, flag); + + /* if endpoint successfully initialised update counter */ + if ((ep_str.ep_num != CONTROL_ENDPOINT) && (status == USB_OK)) + { + g_EPn--; + } + + return status; +} + + +/**************************************************************************//*! + * + * @name _usb_device_deinit_endpoint + * + * @brief The function de-initializes the endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_DEINIT_FAILED : When endpoints > max Supported + ****************************************************************************** + * + * This function deinitializes an endpoint the Device layer and the Controller + * layer in the S08 USB stack. It validate whether all endpoints have already + * been deinitialized or not and then calls the controller layer endpoint + * deinitialize function + * + *****************************************************************************/ +uint_8 _usb_device_deinit_endpoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Direction */ +) +{ + uint_8 status=USB_OK; + + /* check if all endpoint have already been initialised */ + if((g_EPn == g_EPn_max) && (endpoint_number != CONTROL_ENDPOINT)) + { + return USBERR_EP_DEINIT_FAILED; + } + + /* call controller layer for initiazation */ + status = USB_DCI_Deinit_EndPoint(*((uint_8*)handle), endpoint_number, direction); + + /* if endpoint successfully deinitialised update counter */ + if ((endpoint_number != CONTROL_ENDPOINT) && (status == USB_OK)) + { + g_EPn++; + } + + return status; +} + +/**************************************************************************//*! + * + * @name _usb_device_get_status + * + * @brief The function retrieves various endpoint as well as USB component status + * + * @param handle : USB Device handle + * @param component : USB component + * @param status : Pointer to 16 bit return value + * + * @return status + * USB_OK : When Successfull + * USBERR_BAD_STATUS : When error + * + ****************************************************************************** + * This function retrieves the endpoint as well USB component status which is + * stored by calling USB_Device_Set_Status. This function can be called by Ap- + * plication as well as the DCI layer. + *****************************************************************************/ +uint_8 _usb_device_get_status ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 component, /* [IN] USB component */ + uint_8_ptr status /* [OUT] Pointer to 16 bit return value */ +) +{ + /* get the endpoint number from component input variable */ + uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK); + UNUSED (handle) + + if((component <= USB_STATUS_TEST_MODE) && + (component >= USB_STATUS_DEVICE_STATE)) + { + /* Get the corresponding component status + -1 as components start from 1 */ + *status = g_usb_component_status[component-1]; + } + else if ((component & USB_STATUS_ENDPOINT) && + (ep_num < MAX_SUPPORTED_ENDPOINTS)) + { + /* Get the corresponding endpoint status */ + *status = g_usb_ep_status[ep_num]; + } + else + { + return USBERR_BAD_STATUS; + } + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_device_set_status + * + * @brief The function saves status of endpoints as well as USB components. + * + * @param handle : USB Device handle + * @param component : USB component + * @param setting : Value to be set + * + * @return status + * USB_OK : When Successfull + * USBERR_BAD_STATUS : When error + * + ****************************************************************************** + * This function sets the endpoint as well USB component status which can be + * retrieved by calling _usb_device_get_status. This function can be called by + * Application as well as the DCI layer. + *****************************************************************************/ +uint_8 _usb_device_set_status( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 component, /* [IN] USB Component status to set */ + uint_8 setting /* [IN] Status to set */ +) +{ + /* get the endpoint number from component input variable */ + uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK); + UNUSED (handle) + + if((component <= USB_STATUS_TEST_MODE) && + (component >= USB_STATUS_DEVICE_STATE)) + { + /* + Set the corresponding component setting + -1 as components start from 1 + */ + g_usb_component_status[component-1] = setting; + } + else if ((component & USB_STATUS_ENDPOINT) && + (ep_num < MAX_SUPPORTED_ENDPOINTS)) + { + uint_8 direction = + (uint_8)((component >> USB_COMPONENT_DIRECTION_SHIFT) & + USB_COMPONENT_DIRECTION_MASK); + /* HALT Endpoint */ + if(setting == USB_STATUS_STALLED) + { + _usb_device_stall_endpoint(handle, ep_num, direction); + } + else if((setting == USB_STATUS_IDLE) && + (g_usb_ep_status[ep_num] == USB_STATUS_STALLED)) + { + _usb_device_unstall_endpoint(handle, ep_num, direction); + + if(ep_num == CONTROL_ENDPOINT) + { + direction = (uint_8)((direction == USB_SEND)? + (USB_RECV):(USB_SEND)); + _usb_device_unstall_endpoint(handle, ep_num, direction); + } + } + /* Set the corresponding endpoint setting */ + g_usb_ep_status[ep_num] = setting; + } + else + { + return USBERR_BAD_STATUS; + } + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_device_register_service + * + * @brief The function registers a callback function from the Application layer + * + * @param controller_ID : Controller ID + * @param type : event type or endpoint number + * @param service : callback function pointer + * + * @return status + * USB_OK : When Successfull + * USBERR_ALLOC_SERVICE : When invalid type or already registered + * + ****************************************************************************** + * This function registers a callback function from the application if it is + * called not already registered so that the registered callback function can + * be if the event of that type occurs + *****************************************************************************/ +uint_8 _usb_device_register_service( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 type, /* [IN] type of event or endpoint + number to service */ + USB_SERVICE_CALLBACK service /* [IN] pointer to callback + function */ +) +{ + UNUSED (controller_ID) + UNUSED (service) +#ifdef MULTIPLE_DEVICES + /* check if the type is valid and callback for the type + is not already registered */ + if(((type <= USB_SERVICE_MAX_EP) || + ((type < USB_SERVICE_MAX) && (type >= USB_SERVICE_BUS_RESET))) && + (g_usb_CB[type] == NULL)) + { + + /* register the callback function */ + g_usb_CB[type] = service; + return USB_OK; + } + else + { + return USBERR_ALLOC_SERVICE; + } +#else + UNUSED(type); + return USB_OK; +#endif + +} + +/**************************************************************************//*! + * + * @name _usb_device_unregister_service + * + * @brief The function unregisters an event or endpoint callback function + * + * @param handle : USB Device handle + * @param event_endpoint : event type or endpoint number + * + * @return status + * USB_OK : When Successfull + * USBERR_UNKNOWN_ERROR : When invalid type or not registered + * + ***************************************************************************** + * This function un registers a callback function which has been previously + * registered by the application layer + *****************************************************************************/ +uint_8 _usb_device_unregister_service( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 event_endpoint /* [IN] Endpoint (0 through 15) or event to service */ +) +{ + UNUSED (handle) + /* check if the type is valid and callback for the type + is already registered */ + if(((event_endpoint <= USB_SERVICE_MAX_EP) || + ((event_endpoint < USB_SERVICE_MAX) && (event_endpoint >= USB_SERVICE_BUS_RESET))) && + (g_usb_CB[event_endpoint] != NULL)) + { +#ifdef MULTIPLE_DEVICES + /* unregister the callback */ + g_usb_CB[event_endpoint] = NULL; +#endif + return USB_OK; + } + else + { + return USBERR_UNKNOWN_ERROR; + } +} + +/**************************************************************************//*! + * + * @name USB_Device_Call_Service + * + * @brief The function is a device layer event handler + * + * @param type : Type of service or endpoint + * @param event : Pointer to event structure + * + * @return status + * USB_OK : Always + * + ***************************************************************************** + * + * This function calls the registered service callback function of the applic- + * ation layer based on the type of event received. This function is called + * from the DCI layer. + * + *****************************************************************************/ +uint_8 USB_Device_Call_Service( + uint_8 type, /* [IN] Type of service or endpoint */ + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to event structure */ +) +{ + + if(type == USB_SERVICE_BUS_RESET) + { /* if it is an reset interrupt then reset all status structures */ + USB_Device_Init_Params(); + } + + /* check if the callback is registered or not */ + if(g_usb_CB[type] != NULL) + { + /* call the callback function */ + g_usb_CB[type](event); + } + + return USB_OK; +} + +void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event) +{ + UNUSED(event) + + #if (defined(__CWCC__) || defined(__IAR_SYSTEMS_ICC__)) + asm("nop"); + #elif defined(__GNUC__) + __asm("nop"); + #elif defined (__CC_ARM) + __nop(); + #endif +} + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.c b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.c new file mode 100644 index 0000000..09d2556 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.c @@ -0,0 +1,1193 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_framework.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains USB stack framework module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" /* Contains User Defined Data Types */ +#include "usb_class.h" /* USB class Header File */ +#include "usb_framework.h" /* USB Framework Header File */ +#include "usb_descriptor.h" /* USB descriptor Header File */ +#if defined(__IAR_SYSTEMS_ICC__) +#include +#endif +#ifdef OTG_BUILD +#include "usb_otg_main.h" /* OTG header file */ +#endif +#include +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ +/**************************************************************************** + * Global Variables + ****************************************************************************/ +static USB_SETUP_STRUCT g_setup_pkt; + +/*is used to store the value of data which needs to be sent to the USB +host in response to the standard requests.*/ +static uint_16 g_std_framework_data; +/*used to store the address received in Set Address in the standard request.*/ +static uint_8 g_assigned_address; +/* Framework module callback pointer */ +static USB_CLASS_CALLBACK g_framework_callback=NULL; +/* Other Requests Callback pointer */ +static USB_REQ_FUNC g_other_req_callback=NULL; + +#ifdef DELAYED_PROCESSING +static USB_DEV_EVENT_STRUCT g_f_event; +/* initially no pending request */ +static boolean g_control_pending=FALSE; +#endif + +/* << EST: + * Setter and Getter for callback function pointers, so the application can overwrite them + * See https://mcuoneclipse.com/requests/comment-page-5/#comment-86524 + */ +USB_CLASS_CALLBACK USB_Get_Framework_Callback(void) { + return g_framework_callback; +} + +void USB_Set_Framework_Callback(USB_CLASS_CALLBACK callback) { + g_framework_callback = callback; +} + +USB_REQ_FUNC USB_Get_OtherRequest_Callback(void) { + return g_other_req_callback; +} + +void USB_Set_OtherRequest_Callback(USB_REQ_FUNC callback) { + g_other_req_callback = callback; +} +/* << EST end */ + +boolean const g_validate_request[MAX_STRD_REQ][3] = +{ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Get_Status*/ + /* configured state: valid for existing interfaces/endpoints + address state : valid only for interface or endpoint 0 + default state : not specified + */ + {TRUE,TRUE,FALSE}, /* Clear Feature */ + /* configured state: valid only for device in configured state + address state : valid only for device (in address state), + interface and endpoint 0 + default state : not specified + */ + {FALSE,FALSE,FALSE}, /*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ +#ifdef OTG_BUILD + {TRUE,TRUE,TRUE}, /* Set Feature */ + /* configured state: A B-device that supports OTG features + address state : shall be able to accept the SetFeature command + default state : in the Default, Addressed and Configured states + */ +#else + {TRUE,TRUE,FALSE}, /* Set Feature */ + /* configured state: valid only for device in configured state + address state : valid only for interface or endpoint 0 + default state : not specified + */ +#endif + + {FALSE,FALSE,FALSE},/*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {FALSE,TRUE,TRUE}, /*USB_Strd_Req_Set_Address*/ + /* configured state: not specified + address state : changes to default state if specified addr == 0, + but uses newly specified address + default state : changes to address state if specified addr != 0 + */ + {TRUE,TRUE,TRUE}, /*USB_Strd_Req_Get_Descriptor*/ + /* configured state: valid request + address state : valid request + default state : valid request + */ + {FALSE,FALSE,FALSE}, /*Set Descriptor*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Get_Config*/ + /* configured state: bConfiguration Value of current config returned + address state : value zero must be returned + default state : not specified + */ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Set_Config*/ + /* configured state: If the specified configuration value is zero, + then the device enters the Address state.If the + specified configuration value matches the + configuration value from a config descriptor, + then that config is selected and the device + remains in the Configured state. Otherwise, the + device responds with a Request Error. + + address state : If the specified configuration value is zero, + then the device remains in the Address state. If + the specified configuration value matches the + configuration value from a configuration + descriptor, then that configuration is selected + and the device enters the Configured state. + Otherwise,response is Request Error. + default state : not specified + */ + {TRUE,FALSE,FALSE}, /*USB_Strd_Req_Get_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {TRUE,FALSE,FALSE}, /*USB_Strd_Req_Set_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {TRUE,FALSE,FALSE} /*USB_Strd_Req_Sync_Frame*/ + /* configured state: valid request + address state : request error + default state : not specified + */ +}; +/***************************************************************************** + * Global Functions Prototypes - None + *****************************************************************************/ + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +void USB_Control_Service (PTR_USB_DEV_EVENT_STRUCT event ); +static void USB_Control_Service_Handler(uint_8 controller_ID, + uint_8 status, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Status(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Feature(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Address(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Assign_Address(uint_8 controller_ID); +static uint_8 USB_Strd_Req_Get_Config(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Config(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Interface(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Interface(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Sync_Frame(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Descriptor(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +#ifdef DELAYED_PROCESSING +static void USB_Control_Service_Callback(PTR_USB_DEV_EVENT_STRUCT event ); +#endif + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ +static uint_8 ext_req_to_host[USB_OUT_PKT_SIZE + USB_SETUP_PKT_SIZE];/* used for extended OUT transactions on + CONTROL ENDPOINT*/ +/***************************************************************************** + * Global Variables + *****************************************************************************/ +USB_REQ_FUNC +#if 0 /* << EST */ +#if ((!defined(_MC9S08MM128_H)) && (!defined(_MC9S08JE128_H))) +const +#endif +#else +/* device is Kinetis K20D50 << EST */ +const +#endif +g_standard_request[MAX_STRD_REQ] = +{ + USB_Strd_Req_Get_Status, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Set_Address, + USB_Strd_Req_Get_Descriptor, + NULL, + USB_Strd_Req_Get_Config, + USB_Strd_Req_Set_Config, + USB_Strd_Req_Get_Interface, + USB_Strd_Req_Set_Interface, + USB_Strd_Req_Sync_Frame +}; + +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K20D50 << EST */ +#endif +/**************************************************************************//*! + * + * @name USB_Framework_Init + * + * @brief The function initializes the Class Module + * + * @param controller_ID : Controller ID + * @param class_callback : Class callback pointer + * @param other_req_callback: Other Request Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + ****************************************************************************** + * This function registers the service on the control endpoint + *****************************************************************************/ +uint_8 USB_Framework_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK class_callback, /* Class Callback */ + USB_REQ_FUNC other_req_callback /* Other Request Callback */ +) +{ + uint_8 error=USB_OK; + + /* save input parameters */ + g_framework_callback = class_callback; + g_other_req_callback = other_req_callback; + + /* Register CONTROL service */ + error = _usb_device_register_service(controller_ID, USB_SERVICE_EP0, + +#ifdef DELAYED_PROCESSING + USB_Control_Service_Callback +#else + USB_Control_Service +#endif + ); + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Framework_DeInit + * + * @brief The function De-initializes the Class Module + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + ****************************************************************************** + * This function unregisters control service + *****************************************************************************/ +uint_8 USB_Framework_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 error; + /* Free framwork_callback */ + g_framework_callback = NULL; + + /* Free other_req_callback */ + g_other_req_callback = NULL; + + /* Unregister CONTROL service */ + error = _usb_device_unregister_service(&controller_ID, USB_SERVICE_EP0); + + /* Return error */ + return error; +} +#ifdef DELAYED_PROCESSING +/**************************************************************************//*! + * + * @name USB_Framework_Periodic_Task + * + * @brief The function is called to respond to any control request + * + * @param None + * + * @return None + * + ****************************************************************************** + * This function checks for any pending requests and handles them if any + *****************************************************************************/ +void USB_Framework_Periodic_Task(void) +{ + /* if control request pending to be completed */ + if(g_control_pending==TRUE) + { + /* handle pending control request */ + USB_Control_Service(&g_f_event); + g_control_pending = FALSE; + } +} +#endif +/**************************************************************************//*! + * + * @name USB_Framework_Reset + * + * @brief The function resets the framework + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * + ****************************************************************************** + * This function is used to reset the framework module + *****************************************************************************/ +uint_8 USB_Framework_Reset ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return USB_OK; +} + +#ifdef DELAYED_PROCESSING +/**************************************************************************//*! + * + * @name USB_Control_Service_Callback + * + * @brief The function can be used as a callback function to the service. + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * This function saves the event parameters and queues a pending request + *****************************************************************************/ +void USB_Control_Service_Callback ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* save the event parameters */ + g_f_event.buffer_ptr = event->buffer_ptr; + g_f_event.controller_ID = event->controller_ID; + g_f_event.ep_num = event->ep_num; + g_f_event.setup = event->setup; + g_f_event.len = event->len; + g_f_event.errors = event->errors; + + /* set the pending request flag */ + g_control_pending = TRUE; + +} +#endif + +/**************************************************************************//*! + * + * @name USB_Control_Service + * + * @brief Called upon a completed endpoint 0 transfer + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * This function handles the data sent or received on the control endpoint + *****************************************************************************/ +void USB_Control_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_8 device_state = 0; + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_8_ptr data = NULL; + USB_PACKET_SIZE size; + + /* get the device state */ + (void)_usb_device_get_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + &device_state); + + if (event->setup == TRUE) + { + /* get the setup packet */ + (void)memcpy(&g_setup_pkt, event->buffer_ptr, USB_SETUP_PKT_SIZE); + + /* take care of endianess of the 16 bt fields correctly */ + g_setup_pkt.index = BYTE_SWAP16(g_setup_pkt.index); + g_setup_pkt.value = BYTE_SWAP16(g_setup_pkt.value); + g_setup_pkt.length = BYTE_SWAP16(g_setup_pkt.length); + + /* if the request is standard request */ + if ((g_setup_pkt.request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_STRD) + { + /* if callback is not NULL */ + if (g_standard_request[g_setup_pkt.request] != NULL) + { + /* if the request is valid in this device state */ + if((device_state < USB_STATE_POWERED) && + (g_validate_request[g_setup_pkt.request][device_state] + ==TRUE)) + { + /* Standard Request function pointers */ + status = g_standard_request[g_setup_pkt.request] + (event->controller_ID, &g_setup_pkt, &data, + (USB_PACKET_SIZE *)&size); + } + } + } + else /* for Class/Vendor requests */ + { + /*get the length from the setup_request*/ + size = (USB_PACKET_SIZE)g_setup_pkt.length; + if (size <= USB_OUT_PKT_SIZE) { + if( (size != 0) && + ((g_setup_pkt.request_type & USB_DATA_DIREC_MASK) == + USB_DATA_TO_DEVICE) ) + { + (void)memcpy(ext_req_to_host, &g_setup_pkt, USB_SETUP_PKT_SIZE); + + /* expecting host to send data (OUT TRANSACTION)*/ + (void)_usb_device_recv_data(&(event->controller_ID), + CONTROL_ENDPOINT, ext_req_to_host+USB_SETUP_PKT_SIZE, + (USB_PACKET_SIZE)(size)); + return; + } + else if(g_other_req_callback != NULL)/*call class/vendor request*/ + { + status = g_other_req_callback(event->controller_ID, + &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + } + } + else + { + /* incase of error Stall endpoint */ + USB_Control_Service_Handler(event->controller_ID, + USBERR_INVALID_REQ_TYPE, &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + return; + } + } + + USB_Control_Service_Handler(event->controller_ID, + status, &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + } + /* if its not a setup request */ + else if(device_state == USB_STATE_PENDING_ADDRESS) + { + /* Device state is PENDING_ADDRESS */ + /* Assign the new adddress to the Device */ + (void)USB_Strd_Req_Assign_Address(event->controller_ID); + return; + } + else if( ((g_setup_pkt.request_type & + USB_DATA_DIREC_MASK) == USB_DATA_TO_DEVICE) && + (event->direction == USB_RECV) ) + { + /* execution enters Control Service because of + OUT transaction on CONTROL_ENDPOINT*/ + if(g_other_req_callback != NULL) + { /* class or vendor request */ + size = (USB_PACKET_SIZE)(event->len + USB_SETUP_PKT_SIZE); + status = g_other_req_callback(event->controller_ID, + (USB_SETUP_STRUCT*)(ext_req_to_host), &data, + (USB_PACKET_SIZE*)&size); + } + + USB_Control_Service_Handler(event->controller_ID, + status, &g_setup_pkt, &data, + (USB_PACKET_SIZE*)&size); + } + return; +} + +/**************************************************************************//*! + * + * @name USB_Control_Service_Handler + * + * @brief The function is used to send a response to the Host based. + * + * @param controller_ID : Controller ID + * @param status : Status of request + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return None + * + ****************************************************************************** + * This function sends a response to the data received on the control endpoint. + * the request is decoded in the control service + *****************************************************************************/ +static void USB_Control_Service_Handler ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 status, /* [IN] Device Status */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + if(status == USBERR_INVALID_REQ_TYPE) + { + /* incase of error Stall endpoint */ + (void)_usb_device_set_status(&controller_ID, + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (USB_SEND << USB_COMPONENT_DIRECTION_SHIFT)), + USB_STATUS_STALLED); + } + else /* Need to send Data to the USB Host */ + { + /* send the data prepared by the handlers.*/ + if(*size > setup_packet->length) + { + *size = (USB_PACKET_SIZE)setup_packet->length; + } + + /* send the data to the host */ + (void)USB_Class_Send_Data(controller_ID, + CONTROL_ENDPOINT, *data, *size); + if((setup_packet->request_type & USB_DATA_DIREC_MASK) == + USB_DATA_TO_HOST) + { /* Request was to Get Data from device */ + /* setup rcv to get status from host */ + (void)_usb_device_recv_data(&controller_ID, + CONTROL_ENDPOINT,NULL,0); + } + + } + return; +} +/*************************************************************************//*! + * + * @name USB_Strd_Req_Get_Status + * + * @brief This function is called in response to Get Status request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is called by the host to know the status of the + * device, the interface and the endpoint + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Status ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8_ptr pu8ConfigDesc = NULL; + uint_16 u16DescSize; + uint_8 interface, endpoint = 0; + uint_8 status; + uint_8 device_state = USB_STATE_POWERED; + + + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE_STATE, &device_state); + + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE) + { + #ifdef OTG_BUILD + if(setup_packet->index == USB_WINDEX_OTG_STATUS_SEL) + { + uint_8 temp; + /* Request for Device */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_OTG, &temp); + g_std_framework_data = (uint_16)temp; + g_std_framework_data &= GET_STATUS_OTG_MASK; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *size = OTG_STATUS_SIZE; + } + else + #endif + { + uint_8 device_state1; + + /* Request for Device */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_state1); + g_std_framework_data = (uint_16)device_state1; + g_std_framework_data &= GET_STATUS_DEVICE_MASK; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + + /* Set Self Powered bit in device state according to configuration */ + status = USB_Desc_Get_Descriptor(controller_ID, USB_CONFIG_DESCRIPTOR, + 0, 0, &pu8ConfigDesc, (USB_PACKET_SIZE *)&u16DescSize); + + if((pu8ConfigDesc[7] & SELF_POWERED) != 0) + { + g_std_framework_data |= BYTE_SWAP16(0x0001); + } + else + { + g_std_framework_data &= BYTE_SWAP16(~0x0001); + } + *size = DEVICE_STATUS_SIZE; + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_INTERFACE) + { + /* Request for Interface */ + interface = (uint_8) setup_packet->index; + if((device_state == USB_STATE_ADDRESS) && (interface > 0)) + { + status = USBERR_INVALID_REQ_TYPE; + } + else + { + /* Interface requests always return 0 */ + g_std_framework_data = 0x0000; + *size = INTERFACE_STATUS_SIZE; + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT) + { + /* Request for Endpoint */ + if((device_state == USB_STATE_ADDRESS) && (endpoint > 0)) + { + status = USBERR_INVALID_REQ_TYPE; + } + else + { + uint_8 device_state2; + endpoint = (uint_8)(((uint_8) setup_packet->index) | + USB_STATUS_ENDPOINT); + status = _usb_device_get_status(&controller_ID, + endpoint, + &device_state2); + g_std_framework_data = (uint_16)device_state2; + /* All other fields except HALT must be zero */ + g_std_framework_data &= 0x0001; /* LSB is for the HALT feature */ + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *size = ENDP_STATUS_SIZE; + } + } + + *data = (uint_8_ptr)&g_std_framework_data; + return status; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Feature + * + * @brief This function is called in response to Clear or Set Feature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request, used to set/clear a feature on the device + * (device_remote_wakeup and test_mode) or on the endpoint(ep halt) + *****************************************************************************/ +static uint_8 USB_Strd_Req_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 device_status; + uint_8 set_request; + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_8 epinfo; + uint_8 event; + + UNUSED (data) + + *size=0; + /* Find whether its a clear feature request or a set feature request */ + set_request = (uint_8)((setup_packet->request & USB_SET_REQUEST_MASK) >> 1 ); + + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE) + { + /* Request for Device */ + if(set_request == TRUE) + { + /* Standard Feature Selector */ + if((setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP) || (setup_packet->value == DEVICE_FEATURE_TEST_MODE)) + { + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_status); + + if(status == USB_OK) + { + /* Add the request to be set to the device_status */ + device_status |= (uint_16)(1 << (uint_8)setup_packet->value); + + /* Set the status on the device */ + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE, device_status); + } + } + #ifdef OTG_BUILD + /* OTG Feature Selector */ + else if(setup_packet->value == DEVICE_SET_FEATURE_B_HNP_ENABLE) + { + OTG_DESCRIPTOR_PTR_T otg_desc_ptr; + USB_PACKET_SIZE size; + + status = USB_Desc_Get_Descriptor(controller_ID, USB_OTG_DESCRIPTOR,(uint_8)UNINITIALISED_VAL, + (uint_16)UNINITIALISED_VAL,(uint_8_ptr *)&otg_desc_ptr,&size); + if(status == USB_OK) + { + if(otg_desc_ptr->bmAttributes & USB_OTG_HNP_SUPPORT) + { + _usb_otg_hnp_enable(controller_ID, set_request); + } + } + } + #endif + else + { + status = USBERR_INVALID_REQ_TYPE; + } + } + else //(set_request == FALSE) it is a clear feature request + { + if(setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP) + { + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_status); + + if(status == USB_OK) + { + /* Remove the request to be cleared from device_status */ + device_status &= (uint_16)~(1 << (uint_8)setup_packet->value); + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE, device_status); + } + } + else + { + status = USBERR_INVALID_REQ_TYPE; + } + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT) + { + /* Request for Endpoint */ + epinfo = (uint_8)(setup_packet->index & 0x00FF); + status = _usb_device_set_status(&controller_ID, (uint_8)(epinfo|USB_STATUS_ENDPOINT), set_request); + + event = (uint_8)(set_request ? USB_APP_EP_STALLED : USB_APP_EP_UNSTALLED); + + if(setup_packet->request == CLEAR_FEATURE) + { + uint_8 epnum = epinfo & 0x0f; + uint_8 dir = (epinfo & 0x80) >> 7; + _usb_device_clear_data0_endpoint(epnum,dir); + event = USB_APP_EP_UNSTALLED; // as far as the application is concerned, this is an UNSTALL. + } + + /* Inform the upper layers of stall/unstall */ + g_framework_callback(controller_ID,event,(void*)&epinfo); + } + return status; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Address + * + * @brief This function is called in response to Set Address request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request, saves the new address in a global variable. this + * address is assigned to the device after this transaction completes + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Address ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + UNUSED (data) + *size=0; + /* update device state */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE, USB_STATE_PENDING_ADDRESS); + + /*store the address from setup_packet into assigned_address*/ + g_assigned_address = (uint_8)setup_packet->value; + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Assign_Address + * + * @brief This function assigns the address to the Device + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK: Always + * + ****************************************************************************** + * This function assigns the new address and is called (from the control + * service) after the set address transaction completes + *****************************************************************************/ +static uint_8 USB_Strd_Req_Assign_Address ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + /* Set Device Address */ + (void)_usb_device_set_address(&controller_ID, g_assigned_address); + + /* Set Device state */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE, USB_STATE_ADDRESS); + /* Set Device state */ + (void)_usb_device_set_status(&controller_ID, USB_STATUS_ADDRESS, + g_assigned_address); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Config + * + * @brief This function is called in response to Get Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : Always + * + ****************************************************************************** + * This is a ch9 request and is used to know the currently used configuration + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Config ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 device_status; + + UNUSED(setup_packet) + + *size = CONFIG_SIZE; + (void)_usb_device_get_status(&controller_ID, USB_STATUS_CURRENT_CONFIG, &device_status); + g_std_framework_data = (uint_16)device_status; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *data = (uint_8_ptr)(&g_std_framework_data); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Config + * + * @brief This function is called in response to Set Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used by the host to set the new configuration + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Config ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_16 config_val; + + UNUSED (data) + *size = 0; + status = USB_STATUS_ERROR; + config_val = setup_packet->value; + + if (USB_Desc_Valid_Configation(controller_ID, config_val)) + /*if valid configuration (fn returns boolean value)*/ + { + uint_8 device_state = USB_STATE_CONFIG; + + /* if config_val is 0 */ + if (!config_val) + { + device_state = USB_STATE_ADDRESS ; + } + + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE_STATE, + device_state); + status = _usb_device_set_status(&controller_ID, + USB_STATUS_CURRENT_CONFIG, (uint_8)config_val); + /* + Callback to the app. to let the application know about the new + Configuration + */ + g_framework_callback(controller_ID,USB_APP_CONFIG_CHANGED, + (void *)&config_val); + g_framework_callback(controller_ID,USB_APP_ENUM_COMPLETE, NULL); + } + + return status; + } + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Interface + * + * @brief This function is called in response to Get Interface request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used to know the current interface + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + + /* Request type not for interface */ + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) != USB_REQUEST_SRC_INTERFACE) + { + return USB_STATUS_ERROR; + } + else + { + *size = INTERFACE_SIZE; + status = USB_Desc_Get_Interface(controller_ID,(uint_8)setup_packet->index, + (uint_8_ptr)&g_std_framework_data); + *data = (uint_8_ptr)&g_std_framework_data; + + return status; + } +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Interface + * + * @brief This function is called in response to Set Interface request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : Always + * + ****************************************************************************** + * This is a ch9 request and is used by the host to set the interface + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + + UNUSED (data); + *size=0; + + /* Request type not for interface */ + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) != USB_REQUEST_SRC_INTERFACE) + { + return USB_STATUS_ERROR; + } + else + { + /* Set Interface and alternate interface from setup_packet */ + status = USB_Desc_Set_Interface(controller_ID,(uint_8)setup_packet->index, + (uint_8)setup_packet->value); + + UNUSED (status); + + return USB_OK; + } +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Sync_Frame + * + * @brief This function is called in response to Sync Frame request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This req is used to set and then report an ep's synchronization frame + *****************************************************************************/ +static uint_8 USB_Strd_Req_Sync_Frame ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + uint_8 device_status; + + UNUSED(setup_packet) + *size = FRAME_SIZE; + + /* Get the frame number */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_SOF_COUNT, + &device_status); + g_std_framework_data = (uint_16)device_status; + *data = (uint_8_ptr)&g_std_framework_data; + + return status; +} + + +/**************************************************************************//*! + * + * @name USB_Std_Req_Get_Descriptor + * + * @brief This function is called in response to Get Descriptor request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used to send the descriptor requested by the + * host + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Descriptor ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 type = USB_uint_16_high(setup_packet->value); + uint_16 index = (uint_16)UNINITIALISED_VAL; + uint_8 str_num = (uint_8)UNINITIALISED_VAL; + uint_8 status; + + /* for string descriptor set the language and string number */ + index = setup_packet->index; + /*g_setup_pkt.lValue*/ + str_num = USB_uint_16_low(setup_packet->value); + + /* Call descriptor class to get descriptor */ + status = USB_Desc_Get_Descriptor(controller_ID, type, str_num, index, data, size); + + return status; +} diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.h new file mode 100644 index 0000000..88fc707 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_framework.h @@ -0,0 +1,166 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_framwork.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB Framework module API header function. + * + *****************************************************************************/ + +#ifndef _USB_FRAMEWORK_H +#define _USB_FRAMEWORK_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_class.h" +#include "usb_descriptor.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_STRD_REQ (13) /* Max value of standard request */ +/* size of data to be returned for various Get Desc calls */ +#define DEVICE_STATUS_SIZE (2) +#ifdef OTG_BUILD +#define OTG_STATUS_SIZE (2) +#endif +#define INTERFACE_STATUS_SIZE (2) + +#define CONFIG_SIZE (1) +#define INTERFACE_SIZE (1) +#define FRAME_SIZE (2) +#define ENDP_STATUS_SIZE (2) + +#ifdef OTG_BUILD +#define DEVICE_SET_FEATURE_B_HNP_ENABLE (0x0003) /* B HNP enable SET/CLEAR feature value */ +#define DEVICE_SET_FEATURE_A_HNP_SUPPORT (0x0004) /* A HNP support SET/CLEAR feature value */ +#endif + +/* Standard Feature Selectors */ +#define DEVICE_FEATURE_REMOTE_WAKEUP (0x0001) +#define DEVICE_FEATURE_TEST_MODE (0x0002) +#define DEVICE_SET_FEATURE_MASK ((uint_16)((1<<(DEVICE_FEATURE_REMOTE_WAKEUP)) | (1<<(DEVICE_FEATURE_TEST_MODE)))) +#define DEVICE_CLEAR_FEATURE_MASK ((uint_16)(1<<(DEVICE_FEATURE_REMOTE_WAKEUP))) + + + +#define REPORT_DESCRIPTOR_TYPE (0x22) +#define STRING_DESCRIPTOR_TYPE (0x03) + +/* masks and values for provides of Get Desc information */ +#define USB_REQUEST_SRC_MASK (0x03) +#define USB_REQUEST_SRC_DEVICE (0x00) +#define USB_REQUEST_SRC_INTERFACE (0x01) +#define USB_REQUEST_SRC_ENDPOINT (0x02) + +#define USB_SET_REQUEST_MASK (0x02) + +/* wIndex values for GET_Status */ +#ifdef OTG_BUILD +#define USB_WINDEX_OTG_STATUS_SEL (0xF000) +#endif + +/* for transfer direction check */ +#define USB_DATA_TO_HOST (0x80) +#define USB_DATA_TO_DEVICE (0x00) +#define USB_DATA_DIREC_MASK (0x80) + +#define USB_uint_16_low(x) ((uint_8)x) /* lsb byte */ +#define USB_uint_16_high(x) ((uint_8)(x>>8)) /* msb byte */ + +#ifdef CPU_LITTLE_ENDIAN /* << EST: defined by Processor Expert CPU.h for Kinetis devices (but NOT in for SDK 1.x!) */ + #ifndef LITTLE_ENDIAN /* might be defined already on the compiler command line? */ + #define LITTLE_ENDIAN + #endif +#elif defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* GNU/gcc provides these macros */ + #define LITTLE_ENDIAN +#endif + +#if(defined LITTLE_ENDIAN) +#define BYTE_SWAP16(a) (a) +#else +#define BYTE_SWAP16(a) (uint_16)((((uint_16)(a)&0xFF00)>>8) | \ + (((uint_16)(a)&0x00FF)<<8)) +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern boolean USB_Frame_Remote_Wakeup(uint_8 controller_ID); + +#define USB_Frame_Remote_Wakeup USB_Desc_Remote_Wakeup + +typedef struct _app_data_struct +{ + uint_8_ptr data_ptr; /* pointer to buffer */ + USB_PACKET_SIZE data_size; /* buffer size of endpoint */ +}APP_DATA_STRUCT; + +/* << EST: + * Setter and Getter for callback function pointers, so the application can overwrite them + */ +USB_CLASS_CALLBACK USB_Get_Framework_Callback(void); + +void USB_Set_Framework_Callback(USB_CLASS_CALLBACK callback); + +USB_REQ_FUNC USB_Get_OtherRequest_Callback(void); + +void USB_Set_OtherRequest_Callback(USB_REQ_FUNC callback); +/* << EST end */ + + +extern uint_8 USB_Framework_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK callback, + USB_REQ_FUNC other_req_callback +); + +extern uint_8 USB_Framework_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Framework_Reset ( + uint_8 controller_ID +); +#ifdef DELAYED_PROCESSING +extern void USB_Framework_Periodic_Task(void); +#endif + +#endif + diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/usb_user_config.h b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_user_config.h new file mode 100644 index 0000000..0cc65b4 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/usb_user_config.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_user_config.h << EST 'user_config.h' conflicts with MQX Lite + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains User Modifiable Macros for Virtual COM Loopback + * Application + * + *****************************************************************************/ +#if 0 /* << EST */ +#include "derivative.h" + +#if (defined MCU_MK70F12) || (defined __MCF52277_H__) + #define HIGH_SPEED_DEVICE (0) +#else + #define HIGH_SPEED_DEVICE (0) +#endif + +#if (defined MCU_MK20D7) || (defined MCU_MK40D7) + #define MCGOUTCLK_72_MHZ +#endif + +#if ((defined __MK_xxx_H__)||(defined MCU_mcf51jf128)) + #define KEY_PRESS_SIM_TMR_INTERVAL (1000) /* 2s between simulated key press events */ +#else + #ifdef __MCF52277_H__ + #define BUTTON_PRESS_SIMULATION (1) + #define KEY_PRESS_SIM_TMR_INTERVAL (2000) /* 2s between simulated key press events */ + #endif +#endif + +#else +#include "FSL_USB_Stack_Config.h" + +/* device is Kinetis K20D50 << EST */ +#define HIGH_SPEED_DEVICE (0) + + +#endif +/* + Below two MACROS are required for Virtual COM Loopback + Application to execute +*/ +#define LONG_SEND_TRANSACTION /* support to send large data pkts */ +#define LONG_RECEIVE_TRANSACTION /* support to receive large data pkts */ +#ifndef _MC9S08JS16_H + #define USB_OUT_PKT_SIZE 32 /* Define the maximum data length received from the host */ +#else + #define USB_OUT_PKT_SIZE 16 /* Define the maximum data length received from the host */ +#endif + +/* User Defined MACRO to set number of Timer Objects */ +#define MAX_TIMER_OBJECTS 5 + +#if MAX_TIMER_OBJECTS + /* When Enabled Timer Callback is invoked with an argument */ + #define TIMER_CALLBACK_ARG + #undef TIMER_CALLBACK_ARG +#endif + +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H +#define USB_PACKET_SIZE uint_16 /* support 16/32 bit packet size */ +#else +#define USB_PACKET_SIZE uint_8 /* support 8 bit packet size */ +#endif +#else +/* device is Kinetis K20D50 << EST */ +#define USB_PACKET_SIZE uint_16 /* support 16/32 bit packet size */ +#endif + +#if 0 /* << EST */ +#ifndef _MCF51JM128_H +/* Use double buffered endpoints 5 & 6. To be only used with S08 cores */ +#define DOUBLE_BUFFERING_USED +#endif +#else +/* device is Kinetis K20D50 << EST */ +/* Use double buffered endpoints 5 & 6. To be only used with S08 cores */ +#define DOUBLE_BUFFERING_USED +#endif diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.c b/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.c new file mode 100644 index 0000000..b11d074 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.c @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file wdt_kinetis.c + * + * @author + * + * @version + * + * @date + * + * @brief This file contains the implementation of the Watchdog service routines on CFV2 + *****************************************************************************/ + +#include "types.h" /* User Defined Data Types */ +#include "derivative.h" /* include peripheral declarations */ +#include "wdt_kinetis.h" /* own header with public declarations */ + +/*****************************************************************************/ +void Watchdog_Reset(void) +{ +#if defined(MCU_MKL24Z4) || defined(MCU_MKL25Z4) || defined(MCU_MKL26Z4) || defined(MCU_MKL46Z4) + (void)(RCM_SRS0 |= RCM_SRS0_WDOG_MASK); +#else + (void)(WDOG_REFRESH = 0xA602, WDOG_REFRESH = 0xB480); +#endif +} diff --git a/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.h b/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.h new file mode 100644 index 0000000..8a34a08 --- /dev/null +++ b/Projects/tinyK20_SolderDispenser/Generated_Code/wdt_kinetis.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file Wdt_kinetis.h + * + * @brief This is the header file for the Watchdog service routines on CFV2 + *****************************************************************************/ + + #ifndef _WDT_KINETIS_ + #define _WDT_KINETIS_ + + /***************************************************************************** + * Public functions + * + ****************************************************************************/ + extern void Watchdog_Reset(void); + + #endif /* _INIT_HW_ */ diff --git a/Projects/tinyK20_SolderDispenser/ProcessorExpert.pe b/Projects/tinyK20_SolderDispenser/ProcessorExpert.pe index dcc3d78..731b58f 100644 --- a/Projects/tinyK20_SolderDispenser/ProcessorExpert.pe +++ b/Projects/tinyK20_SolderDispenser/ProcessorExpert.pe @@ -3,7 +3,7 @@
tinyK20_SolderDispenser Tobias - 78 + 79 2019-03-05 Eclipse IDE 1.12.2.RT7_b1550-0615 diff --git a/Projects/tinyK22_OpenPnP_Master/.gitignore b/Projects/tinyK22_OpenPnP_Master/.gitignore index 19ffd11..b52460f 100644 --- a/Projects/tinyK22_OpenPnP_Master/.gitignore +++ b/Projects/tinyK22_OpenPnP_Master/.gitignore @@ -1,6 +1,6 @@ /Debug /Documentation -/Generated_Code +# /Generated_Code /*.g_c /*.g_x /Project_Settings/Components_DEBUG diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/.gdbinit-FreeRTOS-helpers b/Projects/tinyK22_OpenPnP_Master/Generated_Code/.gdbinit-FreeRTOS-helpers new file mode 100644 index 0000000..8718d5a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/.gdbinit-FreeRTOS-helpers @@ -0,0 +1,155 @@ +################################################################################# +# .gdbinit-FreeRTOS-helpers +# +# Created on: 29.03.2013 +# Author: Artem Pisarenko +# +# Helper script providing support for FreeRTOS-aware debugging +# Supported architectures: Cortex-M3 +# Features: +# - showing tasks (handle and name); +# - switching context to specified task from almost any context (excluding system exceptions); +# - restore current running context. +################################################################################# + +# Command "freertos_show_threads" +# Shows tasks table: handle(xTaskHandle) and name +define freertos_show_threads + set $thread_list_size = 0 + set $thread_list_size = uxCurrentNumberOfTasks + if ($thread_list_size == 0) + echo FreeRTOS missing or scheduler isn't started\n + else + set $current_thread = pxCurrentTCB + set $tasks_found = 0 + set $idx = 0 + + set $task_list = pxReadyTasksLists + set $task_list_size = sizeof(pxReadyTasksLists)/sizeof(pxReadyTasksLists[0]) + while ($idx < $task_list_size) + _freertos_show_thread_item $task_list[$idx] + set $idx = $idx + 1 + end + + _freertos_show_thread_item xDelayedTaskList1 + _freertos_show_thread_item xDelayedTaskList2 + _freertos_show_thread_item xPendingReadyList + + set $VAL_dbgFreeRTOSConfig_suspend = dbgFreeRTOSConfig_suspend_value + if ($VAL_dbgFreeRTOSConfig_suspend != 0) + _freertos_show_thread_item xSuspendedTaskList + end + + set $VAL_dbgFreeRTOSConfig_delete = dbgFreeRTOSConfig_delete_value + if ($VAL_dbgFreeRTOSConfig_delete != 0) + _freertos_show_thread_item xTasksWaitingTermination + end + end +end + +# Command "freertos_switch_to_task" +# Switches debugging context to specified task, argument - task handle +define freertos_switch_to_task + set var dbgPendingTaskHandle = $arg0 + set $current_IPSR_val = $xpsr & 0xFF + if (($current_IPSR_val >= 1) && ($current_IPSR_val <= 15)) + echo Switching from system exception context isn't supported + else + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + set $last_PRIMASK_val = $PRIMASK + set $last_SCB_ICSR_val = *((volatile unsigned long *)0xE000ED04) + set $last_SYSPRI2_val = *((volatile unsigned long *)0xE000ED20) + set $last_SCB_CCR_val = *((volatile unsigned long *)0xE000ED14) + set $running_IPSR_val = $current_IPSR_val + set $PRIMASK = 0 + # *(portNVIC_SYSPRI2) &= ~(255 << 16) // temporary increase PendSV priority to highest + set {unsigned int}0xe000ed20 = ($last_SYSPRI2_val & (~(255 << 16))) + # set SCB->CCR NONBASETHRDENA bit (allows processor enter thread mode from at any execution priority level) + set {unsigned int}0xE000ED14 = (1) | $last_SCB_CCR_val + set var dbgPendSVHookState = 1 + end + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + stepi + stepi + # here we get rewound to task + end +end + +# Command "freertos_restore_running_context" +# Restores context of running task +define freertos_restore_running_context + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + echo Current task is RUNNING, ignoring command... + else + set var dbgPendingTaskHandle = (void *)pxCurrentTCB + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # check what execution mode was in context we started to switch from + if ($running_IPSR_val == 0) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + else + # force returning to handler mode + set $lr = 0xFFFFFFF1 + end + stepi + stepi + # here we get rewound to running task at place we started switching + # restore processor state + set $PRIMASK = $last_PRIMASK_val + set {unsigned int}0xe000ed20 = $last_SYSPRI2_val + set {unsigned int}0xE000ED14 = $last_SCB_CCR_val + if ($last_SCB_ICSR_val & (1 << 28)) + set {unsigned int}0xe000ed04 = 0x10000000 + end + set var dbgPendSVHookState = 0 + end +end + +# Command "show_broken_backtrace" +# Workaround of issue when context is being stuck in the middle of function epilogue (i.e., in vTaskDelay()) +# This solution is applied to following situation only: +### ... function body end +### xxxxxxxx+0: add.w r7, r7, #16 +### xxxxxxxx+4: mov sp, r7 ; <- debug current instruction pointer +### xxxxxxxx+6: pop {r7, pc} +### } +# (Otherwise it will crash !) +define show_broken_backtrace + # cancel effect of xxxxxxxx+4 instruction twice (because we will step it to update eclipse views) + set $r7 = $r7 - 16 - 16 + set $pc = $pc - 4 + stepi +end + + +####################### +# Internal functions +define _freertos_show_thread_item + set $list_thread_count = $arg0.uxNumberOfItems + set $prev_list_elem_ptr = -1 + set $list_elem_ptr = $arg0.xListEnd.pxPrevious + while (($list_thread_count > 0) && ($list_elem_ptr != 0) && ($list_elem_ptr != $prev_list_elem_ptr) && ($tasks_found < $thread_list_size)) + set $threadid = $list_elem_ptr->pvOwner + set $thread_name_str = (*((tskTCB *)$threadid)).pcTaskName + set $tasks_found = $tasks_found + 1 + set $list_thread_count = $list_thread_count - 1 + set $prev_list_elem_ptr = $list_elem_ptr + set $list_elem_ptr = $prev_list_elem_ptr->pxPrevious + if ($threadid == $current_thread) + printf "0x%x\t%s\t\t<---RUNNING\n", $threadid, $thread_name_str + else + printf "0x%x\t%s\n", $threadid, $thread_name_str + end + end +end + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.c new file mode 100644 index 0000000..7f25c8d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.c @@ -0,0 +1,637 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS1 +** Channel : LPUART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_LPUART0 +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_LPUART0 +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_LPUART0 +** Interrupt Error priority : medium priority +** Input buffer size : 64 +** Output buffer size : 128 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Transmitter : Enabled +** TxD : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS1_RecvChar(AS1_TComData *Chr); +** SendChar - byte AS1_SendChar(AS1_TComData Chr); +** RecvBlock - byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS1_ClearRxBuf(void); +** ClearTxBuf - byte AS1_ClearTxBuf(void); +** GetCharsInRxBuf - word AS1_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS1_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS1.c +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS1_module AS1 module documentation +** @{ +*/ + +/* MODULE AS1. */ + +#include "AS1.h" +#include "Events.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OVERRUN_ERR 0x01U /* Overrun error flag bit */ +#define FRAMING_ERR 0x02U /* Framing error flag bit */ +#define PARITY_ERR 0x04U /* Parity error flag bit */ +#define CHAR_IN_RX 0x08U /* Char is in RX buffer */ +#define FULL_TX 0x10U /* Full transmit buffer */ +#define RUNINT_FROM_TX 0x20U /* Interrupt is in progress */ +#define FULL_RX 0x40U /* Full receive buffer */ +#define NOISE_ERR 0x80U /* Noise error flag bit */ +#define IDLE_ERR 0x0100U /* Idle character flag bit */ +#define BREAK_ERR 0x0200U /* Break detect */ +#define COMMON_ERR 0x0800U /* Common error of RX */ + +LDD_TDeviceData *ASerialLdd1_DeviceDataPtr; /* Device data pointer */ +static word SerFlag; /* Flags for serial communication */ + /* Bits: 0 - OverRun error */ + /* 1 - Framing error */ + /* 2 - Parity error */ + /* 3 - Char in RX buffer */ + /* 4 - Full TX buffer */ + /* 5 - Running int from TX */ + /* 6 - Full RX buffer */ + /* 7 - Noise error */ + /* 8 - Idle character */ + /* 9 - Break detected */ + /* 10 - Unused */ + /* 11 - Unused */ +static word AS1_InpLen; /* Length of input buffer's content */ +static word InpIndexR; /* Index for reading from input buffer */ +static word InpIndexW; /* Index for writing to input buffer */ +static AS1_TComData InpBuffer[AS1_INP_BUF_SIZE]; /* Input buffer for SCI communication */ +static AS1_TComData BufferRead; /* Input char for SCI communication */ +static word AS1_OutLen; /* Length of output bufer's content */ +static word OutIndexR; /* Index for reading from output buffer */ +static word OutIndexW; /* Index for writing to output buffer */ +static AS1_TComData OutBuffer[AS1_OUT_BUF_SIZE]; /* Output buffer for SCI communication */ +static bool OnFreeTxBufSemaphore; /* Disable the false calling of the OnFreeTxBuf event */ + +/* +** =================================================================== +** Method : HWEnDi (component AsynchroSerial) +** +** Description : +** Enables or disables the peripheral(s) associated with the bean. +** The method is called automatically as a part of the Enable and +** Disable methods and several internal methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void HWEnDi(void) +{ + (void)ASerialLdd1_ReceiveBlock(ASerialLdd1_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +/* +** =================================================================== +** Method : AS1_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvChar(AS1_TComData *Chr) +{ + byte Result = ERR_OK; /* Return error code */ + + if (AS1_InpLen > 0x00U) { /* Is number of received chars greater than 0? */ + EnterCritical(); /* Disable global interrupts */ + AS1_InpLen--; /* Decrease number of received chars */ + *Chr = InpBuffer[InpIndexR++]; /* Received char */ + if (InpIndexR >= AS1_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexR = 0x00U; /* Set index to the first item into the receive buffer */ + } + Result = (byte)((SerFlag & (OVERRUN_ERR|COMMON_ERR|FULL_RX))? ERR_COMMON : ERR_OK); + SerFlag &= (word)~(word)(OVERRUN_ERR|COMMON_ERR|FULL_RX|CHAR_IN_RX); /* Clear all errors in the status variable */ + ExitCritical(); /* Enable global interrupts */ + } else { + return ERR_RXEMPTY; /* Receiver is empty */ + } + return Result; /* Return error code */ +} + +/* +** =================================================================== +** Method : AS1_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS1_SendChar(AS1_TComData Chr) +{ + if (AS1_OutLen == AS1_OUT_BUF_SIZE) { /* Is number of chars in buffer is the same as a size of the transmit buffer */ + return ERR_TXFULL; /* If yes then error */ + } + EnterCritical(); /* Disable global interrupts */ + AS1_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = Chr; /* Store char to buffer */ + if (OutIndexW >= AS1_OUT_BUF_SIZE) { /* Is the pointer out of the transmit buffer */ + OutIndexW = 0x00U; /* Set index to first item in the transmit buffer */ + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv) +{ + register word count; /* Number of received chars */ + register byte result = ERR_OK; /* Last error */ + + for (count = 0x00U; count < Size; count++) { + switch (AS1_RecvChar(Ptr++)) { /* Receive data and test the return value*/ + case ERR_RXEMPTY: /* No data in the buffer */ + if (result == ERR_OK) { /* If no receiver error reported */ + result = ERR_RXEMPTY; /* Return info that requested number of data is not available */ + } + *Rcv = count; /* Return number of received chars */ + return result; + case ERR_COMMON: /* Receiver error reported */ + result = ERR_COMMON; /* Return info that an error was detected */ + break; + default: + break; + } + } + *Rcv = count; /* Return number of received chars */ + return result; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd) +{ + word count = 0x00U; /* Number of sent chars */ + AS1_TComData *TmpPtr = Ptr; /* Temporary output buffer pointer */ + bool tmpOnFreeTxBufSemaphore = OnFreeTxBufSemaphore; /* Local copy of OnFreeTxBufSemaphore state */ + + while ((count < Size) && (AS1_OutLen < AS1_OUT_BUF_SIZE)) { /* While there is some char desired to send left and output buffer is not full do */ + EnterCritical(); /* Enter the critical section */ + OnFreeTxBufSemaphore = TRUE; /* Set the OnFreeTxBufSemaphore to block OnFreeTxBuf calling */ + AS1_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = *TmpPtr++; /* Store char to buffer */ + if (OutIndexW >= AS1_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexW = 0x00U; /* Set index to the first item in the transmit buffer */ + } + count++; /* Increase the count of sent data */ + if ((count == Size) || (AS1_OutLen == AS1_OUT_BUF_SIZE)) { /* Is the last desired char put into buffer or the buffer is full? */ + if (!tmpOnFreeTxBufSemaphore) { /* Was the OnFreeTxBufSemaphore clear before enter the method? */ + OnFreeTxBufSemaphore = FALSE; /* If yes then clear the OnFreeTxBufSemaphore */ + } + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Exit the critical section */ + } + *Snd = count; /* Return number of sent chars */ + if (count != Size) { /* Is the number of sent chars less then desired number of chars */ + return ERR_TXFULL; /* If yes then error */ + } + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearRxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS1_InpLen = 0x00U; /* Set number of chars in the transmit buffer to 0 */ + InpIndexW = 0x00U; /* Set index on the first item in the transmit buffer */ + InpIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearTxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS1_OutLen = 0x00U; /* Set number of chars in the receive buffer to 0 */ + OutIndexW = 0x00U; /* Set index on the first item in the receive buffer */ + OutIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInRxBuf(void) +{ + return AS1_InpLen; /* Return number of chars in receive buffer */ +} + +/* +** =================================================================== +** Method : AS1_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInTxBuf(void) +{ + return AS1_OutLen; /* Return number of chars in the transmitter buffer */ +} + +/* +** =================================================================== +** Method : AS1_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS1_Init(void) +{ + SerFlag = 0x00U; /* Reset flags */ + AS1_InpLen = 0x00U; /* No char in the receive buffer */ + InpIndexR = 0x00U; /* Set index on the first item in the receive buffer */ + InpIndexW = 0x00U; + AS1_OutLen = 0x00U; /* No char in the transmit buffer */ + OutIndexR = 0x00U; /* Set index on the first item in the transmit buffer */ + OutIndexW = 0x00U; + ASerialLdd1_DeviceDataPtr = ASerialLdd1_Init(NULL); /* Calling init method of the inherited component */ + HWEnDi(); /* Enable/disable device according to status flags */ +} + +#define ON_ERROR 0x01U +#define ON_FULL_RX 0x02U +#define ON_RX_CHAR 0x04U +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockReceived(LDD_TUserData *UserDataPtr) +{ + register byte Flags = 0U; /* Temporary variable for flags */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (AS1_InpLen < AS1_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer lower than size of buffer? */ + AS1_InpLen++; /* Increase number of chars in the receive buffer */ + InpBuffer[InpIndexW++] = (AS1_TComData)BufferRead; /* Save received char to the receive buffer */ + if (InpIndexW >= AS1_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexW = 0x00U; /* Set index on the first item into the receive buffer */ + } + Flags |= ON_RX_CHAR; /* If yes then set the OnRxChar flag */ + if (AS1_InpLen == AS1_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer equal to the size of buffer? */ + Flags |= ON_FULL_RX; /* Set flag "OnFullRxBuf" */ + } + } else { + SerFlag |= FULL_RX; /* Set flag "full RX buffer" */ + Flags |= ON_ERROR; /* Set the OnError flag */ + } + if ((Flags & ON_ERROR) != 0U) { /* Is any error flag set? */ + AS1_OnError(); /* Invoke user event */ + } else { + if ((Flags & ON_RX_CHAR) != 0U) { /* Is OnRxChar flag set? */ + AS1_OnRxChar(); /* Invoke user event */ + } + if ((Flags & ON_FULL_RX) != 0U) { /* Is OnTxChar flag set? */ + AS1_OnFullRxBuf(); /* Invoke user event */ + } + } + (void)ASerialLdd1_ReceiveBlock(ASerialLdd1_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +#define ON_FREE_TX 0x01U +#define ON_TX_CHAR 0x02U +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockSent(LDD_TUserData *UserDataPtr) +{ + word OnFlags = 0x00U; /* Temporary variable for flags */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if ((SerFlag & RUNINT_FROM_TX) != 0U) { /* Is flag "running int from TX" set? */ + OnFlags |= ON_TX_CHAR; /* Set flag "OnTxChar" */ + } + OutIndexR++; + if (OutIndexR >= AS1_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexR = 0x00U; /* Set index on the first item into the transmit buffer */ + } + AS1_OutLen--; /* Decrease number of chars in the transmit buffer */ + if (AS1_OutLen != 0U) { /* Is number of bytes in the transmit buffer greater then 0? */ + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } else { + SerFlag &= (byte)~(RUNINT_FROM_TX); /* Clear "running int from TX" and "full TX buff" flags */ + if (!(OnFreeTxBufSemaphore)) { /* Is the OnFreeTXBuf flag blocked ?*/ + OnFlags |= ON_FREE_TX; /* If not, set the OnFreeTxBuf flag */ + } + } + if ((OnFlags & ON_TX_CHAR) != 0x00U) { /* Is flag "OnTxChar" set? */ + AS1_OnTxChar(); /* If yes then invoke user event */ + } + if ((OnFlags & ON_FREE_TX) != 0x00U) { /* Is flag "OnFreeTxBuf" set? */ + AS1_OnFreeTxBuf(); /* If yes then invoke user event */ + } +} + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnError(LDD_TUserData *UserDataPtr) +{ + LDD_SERIAL_TError SerialErrorMask; /* Serial error mask variable */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + (void)ASerialLdd1_GetError(ASerialLdd1_DeviceDataPtr, &SerialErrorMask); /* Get error state */ + if (SerialErrorMask != 0U) { + SerFlag |= (((SerialErrorMask & LDD_SERIAL_PARITY_ERROR) != 0U ) ? PARITY_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_NOISE_ERROR) != 0U ) ? NOISE_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_RX_OVERRUN) != 0U ) ? OVERRUN_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_FRAMING_ERROR) != 0U ) ? FRAMING_ERR : 0U); + } + AS1_OnError(); /* Invoke user event */ +} + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBreak(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + SerFlag |= FRAMING_ERR; /* Set framing error flag */ +} + + +/* END AS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.h new file mode 100644 index 0000000..75719d1 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS1.h @@ -0,0 +1,415 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS1 +** Channel : LPUART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_LPUART0 +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_LPUART0 +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_LPUART0 +** Interrupt Error priority : medium priority +** Input buffer size : 64 +** Output buffer size : 128 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Transmitter : Enabled +** TxD : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS1_RecvChar(AS1_TComData *Chr); +** SendChar - byte AS1_SendChar(AS1_TComData Chr); +** RecvBlock - byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS1_ClearRxBuf(void); +** ClearTxBuf - byte AS1_ClearTxBuf(void); +** GetCharsInRxBuf - word AS1_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS1_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS1.h +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS1_module AS1 module documentation +** @{ +*/ + +#ifndef __AS1 +#define __AS1 + +/* MODULE AS1. */ + +/* Include inherited components */ +#include "ASerialLdd1.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef __BWUserType_AS1_TError +#define __BWUserType_AS1_TError + typedef union { + byte err; + struct { + bool OverRun : 1; /* Overrun error flag */ + bool Framing : 1; /* Framing error flag */ + bool Parity : 1; /* Parity error flag */ + bool RxBufOvf : 1; /* Rx buffer full error flag */ + bool Noise : 1; /* Noise error flag */ + bool Break : 1; /* Break detect */ + bool LINSync : 1; /* LIN synchronization error */ + bool BitError : 1; /* Bit error flag - mismatch to the expected value happened. */ + } errName; +} AS1_TError; /* Error flags. For languages which don't support bit access is byte access only to error flags possible. */ +#endif + +#ifndef __BWUserType_AS1_TComData +#define __BWUserType_AS1_TComData + typedef byte AS1_TComData; /* User type for communication. Size of this type depends on the communication data witdh */ +#endif + +#define AS1_INP_BUF_SIZE 0x40U /* Length of the RX buffer */ + +#define AS1_OUT_BUF_SIZE 0x80U /* Length of the TX buffer */ + +/* +** =================================================================== +** Method : AS1_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvChar(AS1_TComData *Chr); + +/* +** =================================================================== +** Method : AS1_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS1_SendChar(AS1_TComData Chr); + +/* +** =================================================================== +** Method : AS1_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvBlock(AS1_TComData *Ptr,word Size,word *Rcv); + +/* +** =================================================================== +** Method : AS1_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS1_SendBlock(AS1_TComData *Ptr,word Size,word *Snd); + +/* +** =================================================================== +** Method : AS1_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearRxBuf(void); + +/* +** =================================================================== +** Method : AS1_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearTxBuf(void); + +/* +** =================================================================== +** Method : AS1_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInRxBuf(void); + +/* +** =================================================================== +** Method : AS1_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInTxBuf(void); + +/* +** =================================================================== +** Method : AS1_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS1_Init(void); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockReceived(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockSent(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnError(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBreak(LDD_TUserData *UserDataPtr); + + +/* END AS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef __AS1 */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.c new file mode 100644 index 0000000..a4ba26c --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.c @@ -0,0 +1,637 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS2.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS2 +** Channel : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : medium priority +** Input buffer size : 64 +** Output buffer size : 64 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Transmitter : Enabled +** TxD : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS2_RecvChar(AS2_TComData *Chr); +** SendChar - byte AS2_SendChar(AS2_TComData Chr); +** RecvBlock - byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS2_ClearRxBuf(void); +** ClearTxBuf - byte AS2_ClearTxBuf(void); +** GetCharsInRxBuf - word AS2_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS2_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS2.c +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS2_module AS2 module documentation +** @{ +*/ + +/* MODULE AS2. */ + +#include "AS2.h" +#include "Events.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OVERRUN_ERR 0x01U /* Overrun error flag bit */ +#define FRAMING_ERR 0x02U /* Framing error flag bit */ +#define PARITY_ERR 0x04U /* Parity error flag bit */ +#define CHAR_IN_RX 0x08U /* Char is in RX buffer */ +#define FULL_TX 0x10U /* Full transmit buffer */ +#define RUNINT_FROM_TX 0x20U /* Interrupt is in progress */ +#define FULL_RX 0x40U /* Full receive buffer */ +#define NOISE_ERR 0x80U /* Noise error flag bit */ +#define IDLE_ERR 0x0100U /* Idle character flag bit */ +#define BREAK_ERR 0x0200U /* Break detect */ +#define COMMON_ERR 0x0800U /* Common error of RX */ + +LDD_TDeviceData *ASerialLdd2_DeviceDataPtr; /* Device data pointer */ +static word SerFlag; /* Flags for serial communication */ + /* Bits: 0 - OverRun error */ + /* 1 - Framing error */ + /* 2 - Parity error */ + /* 3 - Char in RX buffer */ + /* 4 - Full TX buffer */ + /* 5 - Running int from TX */ + /* 6 - Full RX buffer */ + /* 7 - Noise error */ + /* 8 - Idle character */ + /* 9 - Break detected */ + /* 10 - Unused */ + /* 11 - Unused */ +static word AS2_InpLen; /* Length of input buffer's content */ +static word InpIndexR; /* Index for reading from input buffer */ +static word InpIndexW; /* Index for writing to input buffer */ +static AS2_TComData InpBuffer[AS2_INP_BUF_SIZE]; /* Input buffer for SCI communication */ +static AS2_TComData BufferRead; /* Input char for SCI communication */ +static word AS2_OutLen; /* Length of output bufer's content */ +static word OutIndexR; /* Index for reading from output buffer */ +static word OutIndexW; /* Index for writing to output buffer */ +static AS2_TComData OutBuffer[AS2_OUT_BUF_SIZE]; /* Output buffer for SCI communication */ +static bool OnFreeTxBufSemaphore; /* Disable the false calling of the OnFreeTxBuf event */ + +/* +** =================================================================== +** Method : HWEnDi (component AsynchroSerial) +** +** Description : +** Enables or disables the peripheral(s) associated with the bean. +** The method is called automatically as a part of the Enable and +** Disable methods and several internal methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void HWEnDi(void) +{ + (void)ASerialLdd2_ReceiveBlock(ASerialLdd2_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +/* +** =================================================================== +** Method : AS2_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvChar(AS2_TComData *Chr) +{ + byte Result = ERR_OK; /* Return error code */ + + if (AS2_InpLen > 0x00U) { /* Is number of received chars greater than 0? */ + EnterCritical(); /* Disable global interrupts */ + AS2_InpLen--; /* Decrease number of received chars */ + *Chr = InpBuffer[InpIndexR++]; /* Received char */ + if (InpIndexR >= AS2_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexR = 0x00U; /* Set index to the first item into the receive buffer */ + } + Result = (byte)((SerFlag & (OVERRUN_ERR|COMMON_ERR|FULL_RX))? ERR_COMMON : ERR_OK); + SerFlag &= (word)~(word)(OVERRUN_ERR|COMMON_ERR|FULL_RX|CHAR_IN_RX); /* Clear all errors in the status variable */ + ExitCritical(); /* Enable global interrupts */ + } else { + return ERR_RXEMPTY; /* Receiver is empty */ + } + return Result; /* Return error code */ +} + +/* +** =================================================================== +** Method : AS2_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS2_SendChar(AS2_TComData Chr) +{ + if (AS2_OutLen == AS2_OUT_BUF_SIZE) { /* Is number of chars in buffer is the same as a size of the transmit buffer */ + return ERR_TXFULL; /* If yes then error */ + } + EnterCritical(); /* Disable global interrupts */ + AS2_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = Chr; /* Store char to buffer */ + if (OutIndexW >= AS2_OUT_BUF_SIZE) { /* Is the pointer out of the transmit buffer */ + OutIndexW = 0x00U; /* Set index to first item in the transmit buffer */ + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv) +{ + register word count; /* Number of received chars */ + register byte result = ERR_OK; /* Last error */ + + for (count = 0x00U; count < Size; count++) { + switch (AS2_RecvChar(Ptr++)) { /* Receive data and test the return value*/ + case ERR_RXEMPTY: /* No data in the buffer */ + if (result == ERR_OK) { /* If no receiver error reported */ + result = ERR_RXEMPTY; /* Return info that requested number of data is not available */ + } + *Rcv = count; /* Return number of received chars */ + return result; + case ERR_COMMON: /* Receiver error reported */ + result = ERR_COMMON; /* Return info that an error was detected */ + break; + default: + break; + } + } + *Rcv = count; /* Return number of received chars */ + return result; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd) +{ + word count = 0x00U; /* Number of sent chars */ + AS2_TComData *TmpPtr = Ptr; /* Temporary output buffer pointer */ + bool tmpOnFreeTxBufSemaphore = OnFreeTxBufSemaphore; /* Local copy of OnFreeTxBufSemaphore state */ + + while ((count < Size) && (AS2_OutLen < AS2_OUT_BUF_SIZE)) { /* While there is some char desired to send left and output buffer is not full do */ + EnterCritical(); /* Enter the critical section */ + OnFreeTxBufSemaphore = TRUE; /* Set the OnFreeTxBufSemaphore to block OnFreeTxBuf calling */ + AS2_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = *TmpPtr++; /* Store char to buffer */ + if (OutIndexW >= AS2_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexW = 0x00U; /* Set index to the first item in the transmit buffer */ + } + count++; /* Increase the count of sent data */ + if ((count == Size) || (AS2_OutLen == AS2_OUT_BUF_SIZE)) { /* Is the last desired char put into buffer or the buffer is full? */ + if (!tmpOnFreeTxBufSemaphore) { /* Was the OnFreeTxBufSemaphore clear before enter the method? */ + OnFreeTxBufSemaphore = FALSE; /* If yes then clear the OnFreeTxBufSemaphore */ + } + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Exit the critical section */ + } + *Snd = count; /* Return number of sent chars */ + if (count != Size) { /* Is the number of sent chars less then desired number of chars */ + return ERR_TXFULL; /* If yes then error */ + } + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearRxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS2_InpLen = 0x00U; /* Set number of chars in the transmit buffer to 0 */ + InpIndexW = 0x00U; /* Set index on the first item in the transmit buffer */ + InpIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearTxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS2_OutLen = 0x00U; /* Set number of chars in the receive buffer to 0 */ + OutIndexW = 0x00U; /* Set index on the first item in the receive buffer */ + OutIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInRxBuf(void) +{ + return AS2_InpLen; /* Return number of chars in receive buffer */ +} + +/* +** =================================================================== +** Method : AS2_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInTxBuf(void) +{ + return AS2_OutLen; /* Return number of chars in the transmitter buffer */ +} + +/* +** =================================================================== +** Method : AS2_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS2_Init(void) +{ + SerFlag = 0x00U; /* Reset flags */ + AS2_InpLen = 0x00U; /* No char in the receive buffer */ + InpIndexR = 0x00U; /* Set index on the first item in the receive buffer */ + InpIndexW = 0x00U; + AS2_OutLen = 0x00U; /* No char in the transmit buffer */ + OutIndexR = 0x00U; /* Set index on the first item in the transmit buffer */ + OutIndexW = 0x00U; + ASerialLdd2_DeviceDataPtr = ASerialLdd2_Init(NULL); /* Calling init method of the inherited component */ + HWEnDi(); /* Enable/disable device according to status flags */ +} + +#define ON_ERROR 0x01U +#define ON_FULL_RX 0x02U +#define ON_RX_CHAR 0x04U +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockReceived(LDD_TUserData *UserDataPtr) +{ + register byte Flags = 0U; /* Temporary variable for flags */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (AS2_InpLen < AS2_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer lower than size of buffer? */ + AS2_InpLen++; /* Increase number of chars in the receive buffer */ + InpBuffer[InpIndexW++] = (AS2_TComData)BufferRead; /* Save received char to the receive buffer */ + if (InpIndexW >= AS2_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexW = 0x00U; /* Set index on the first item into the receive buffer */ + } + Flags |= ON_RX_CHAR; /* If yes then set the OnRxChar flag */ + if (AS2_InpLen == AS2_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer equal to the size of buffer? */ + Flags |= ON_FULL_RX; /* Set flag "OnFullRxBuf" */ + } + } else { + SerFlag |= FULL_RX; /* Set flag "full RX buffer" */ + Flags |= ON_ERROR; /* Set the OnError flag */ + } + if ((Flags & ON_ERROR) != 0U) { /* Is any error flag set? */ + AS2_OnError(); /* Invoke user event */ + } else { + if ((Flags & ON_RX_CHAR) != 0U) { /* Is OnRxChar flag set? */ + AS2_OnRxChar(); /* Invoke user event */ + } + if ((Flags & ON_FULL_RX) != 0U) { /* Is OnTxChar flag set? */ + AS2_OnFullRxBuf(); /* Invoke user event */ + } + } + (void)ASerialLdd2_ReceiveBlock(ASerialLdd2_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +#define ON_FREE_TX 0x01U +#define ON_TX_CHAR 0x02U +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockSent(LDD_TUserData *UserDataPtr) +{ + word OnFlags = 0x00U; /* Temporary variable for flags */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if ((SerFlag & RUNINT_FROM_TX) != 0U) { /* Is flag "running int from TX" set? */ + OnFlags |= ON_TX_CHAR; /* Set flag "OnTxChar" */ + } + OutIndexR++; + if (OutIndexR >= AS2_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexR = 0x00U; /* Set index on the first item into the transmit buffer */ + } + AS2_OutLen--; /* Decrease number of chars in the transmit buffer */ + if (AS2_OutLen != 0U) { /* Is number of bytes in the transmit buffer greater then 0? */ + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } else { + SerFlag &= (byte)~(RUNINT_FROM_TX); /* Clear "running int from TX" and "full TX buff" flags */ + if (!(OnFreeTxBufSemaphore)) { /* Is the OnFreeTXBuf flag blocked ?*/ + OnFlags |= ON_FREE_TX; /* If not, set the OnFreeTxBuf flag */ + } + } + if ((OnFlags & ON_TX_CHAR) != 0x00U) { /* Is flag "OnTxChar" set? */ + AS2_OnTxChar(); /* If yes then invoke user event */ + } + if ((OnFlags & ON_FREE_TX) != 0x00U) { /* Is flag "OnFreeTxBuf" set? */ + AS2_OnFreeTxBuf(); /* If yes then invoke user event */ + } +} + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnError(LDD_TUserData *UserDataPtr) +{ + LDD_SERIAL_TError SerialErrorMask; /* Serial error mask variable */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + (void)ASerialLdd2_GetError(ASerialLdd2_DeviceDataPtr, &SerialErrorMask); /* Get error state */ + if (SerialErrorMask != 0U) { + SerFlag |= (((SerialErrorMask & LDD_SERIAL_PARITY_ERROR) != 0U ) ? PARITY_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_NOISE_ERROR) != 0U ) ? NOISE_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_RX_OVERRUN) != 0U ) ? OVERRUN_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_FRAMING_ERROR) != 0U ) ? FRAMING_ERR : 0U); + } + AS2_OnError(); /* Invoke user event */ +} + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBreak(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + SerFlag |= FRAMING_ERR; /* Set framing error flag */ +} + + +/* END AS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.h new file mode 100644 index 0000000..a4fc4f8 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/AS2.h @@ -0,0 +1,415 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS2.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS2 +** Channel : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : medium priority +** Input buffer size : 64 +** Output buffer size : 64 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Transmitter : Enabled +** TxD : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS2_RecvChar(AS2_TComData *Chr); +** SendChar - byte AS2_SendChar(AS2_TComData Chr); +** RecvBlock - byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS2_ClearRxBuf(void); +** ClearTxBuf - byte AS2_ClearTxBuf(void); +** GetCharsInRxBuf - word AS2_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS2_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS2.h +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS2_module AS2 module documentation +** @{ +*/ + +#ifndef __AS2 +#define __AS2 + +/* MODULE AS2. */ + +/* Include inherited components */ +#include "ASerialLdd2.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef __BWUserType_AS2_TError +#define __BWUserType_AS2_TError + typedef union { + byte err; + struct { + bool OverRun : 1; /* Overrun error flag */ + bool Framing : 1; /* Framing error flag */ + bool Parity : 1; /* Parity error flag */ + bool RxBufOvf : 1; /* Rx buffer full error flag */ + bool Noise : 1; /* Noise error flag */ + bool Break : 1; /* Break detect */ + bool LINSync : 1; /* LIN synchronization error */ + bool BitError : 1; /* Bit error flag - mismatch to the expected value happened. */ + } errName; +} AS2_TError; /* Error flags. For languages which don't support bit access is byte access only to error flags possible. */ +#endif + +#ifndef __BWUserType_AS2_TComData +#define __BWUserType_AS2_TComData + typedef byte AS2_TComData; /* User type for communication. Size of this type depends on the communication data witdh */ +#endif + +#define AS2_INP_BUF_SIZE 0x40U /* Length of the RX buffer */ + +#define AS2_OUT_BUF_SIZE 0x40U /* Length of the TX buffer */ + +/* +** =================================================================== +** Method : AS2_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvChar(AS2_TComData *Chr); + +/* +** =================================================================== +** Method : AS2_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS2_SendChar(AS2_TComData Chr); + +/* +** =================================================================== +** Method : AS2_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvBlock(AS2_TComData *Ptr,word Size,word *Rcv); + +/* +** =================================================================== +** Method : AS2_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS2_SendBlock(AS2_TComData *Ptr,word Size,word *Snd); + +/* +** =================================================================== +** Method : AS2_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearRxBuf(void); + +/* +** =================================================================== +** Method : AS2_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearTxBuf(void); + +/* +** =================================================================== +** Method : AS2_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInRxBuf(void); + +/* +** =================================================================== +** Method : AS2_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInTxBuf(void); + +/* +** =================================================================== +** Method : AS2_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS2_Init(void); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockReceived(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockSent(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnError(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBreak(LDD_TUserData *UserDataPtr); + + +/* END AS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef __AS2 */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.c new file mode 100644 index 0000000..acca69b --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.c @@ -0,0 +1,524 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd1 +** Device : LPUART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_LPUART0 +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_LPUART0 +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_LPUART0 +** Interrupt Error priority : medium priority +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Transmitter : Enabled +** TxD : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd1.c +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd1_module ASerialLdd1 module documentation +** @{ +*/ + +/* MODULE ASerialLdd1. */ +/*lint -save -e926 -e927 -e928 -e929 -e572 Disable MISRA rule (11.4,12.8) checking. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "ASerialLdd1.h" +#include "AS1.h" +#include "LPUART_PDD.h" +#include "SIM_PDD.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! The mask of available events used to enable/disable events during runtime. */ +#define AVAILABLE_EVENTS_MASK (LDD_SERIAL_ON_BLOCK_RECEIVED | LDD_SERIAL_ON_BLOCK_SENT | LDD_SERIAL_ON_BREAK | LDD_SERIAL_ON_ERROR) + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static ASerialLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd1_TDeviceDataPtr INT_LPUART0__BAREBOARD_RTOS_ISRPARAM; + +/* +** =================================================================== +** Method : ASerialLdd1_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + + /* Clear the receive counters and pointer */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ + DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ + /* Clear the transmit counters and pointer */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Allocate interrupt vectors */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_LPUART0__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC6: LPUART0=1 */ + SIM_SCGC6 |= SIM_SCGC6_LPUART0_MASK; + /* SIM_SCGC5: PORTC=1 */ + SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; + /* PORTC_PCR3: ISF=0,MUX=7 */ + PORTC_PCR3 = (uint32_t)((PORTC_PCR3 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK + )) | (uint32_t)( + PORT_PCR_MUX(0x07) + )); + /* PORTC_PCR4: ISF=0,MUX=7 */ + PORTC_PCR4 = (uint32_t)((PORTC_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK + )) | (uint32_t)( + PORT_PCR_MUX(0x07) + )); + /* NVICIP30: PRI30=0x70 */ + NVICIP30 = NVIC_IP_PRI30(0x70); + /* NVICISER0: SETENA|=0x40000000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x40000000); + LPUART_PDD_EnableTransmitter(LPUART0_BASE_PTR, PDD_DISABLE); /* Disable transmitter. */ + LPUART_PDD_EnableReceiver(LPUART0_BASE_PTR, PDD_DISABLE); /* Disable receiver. */ + DeviceDataPrv->SerFlag = 0x00U; /* Reset flags */ + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* LPUART0_CTRL: R8T9=0,R9T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0,TIE=0,TCIE=0,RIE=0,ILIE=0,TE=0,RE=0,RWU=0,SBK=0,MA1IE=0,MA2IE=0,??=0,??=0,??=0,IDLECFG=0,LOOPS=0,DOZEEN=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */ + LPUART0_CTRL = LPUART_CTRL_IDLECFG(0x00); /* Set the CTRL register */ + /* LPUART0_BAUD: M10=0 */ + LPUART0_BAUD &= (uint32_t)~(uint32_t)(LPUART_BAUD_M10_MASK); /* Disable 10-bit mode */ + /* LPUART0_STAT: LBKDIF=0,RXEDGIF=0,RXINV=0,BRK13=0,IDLE=0,OR=0,NF=0,FE=0,PF=0,MA1F=0,MA2F=0 */ + LPUART0_STAT &= (uint32_t)~(uint32_t)( + LPUART_STAT_LBKDIF_MASK | + LPUART_STAT_RXEDGIF_MASK | + LPUART_STAT_RXINV_MASK | + LPUART_STAT_BRK13_MASK | + LPUART_STAT_IDLE_MASK | + LPUART_STAT_OR_MASK | + LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | + LPUART_STAT_PF_MASK | + LPUART_STAT_MA1F_MASK | + LPUART_STAT_MA2F_MASK + ); /* Set the STATUS register */ + SIM_PDD_SetClockSourceLPUART0(SIM_BASE_PTR, SIM_PDD_LPUART0_PLL_FLL_CLOCK); + LPUART_PDD_SetBaudRate(LPUART0_BASE_PTR, 781U); /* Set the baud rate register. */ + LPUART_PDD_SetOversamplingRatio(LPUART0_BASE_PTR, 3U); + LPUART_PDD_EnableSamplingOnBothEdges(LPUART0_BASE_PTR, PDD_ENABLE); + LPUART_PDD_EnableTransmitter(LPUART0_BASE_PTR, PDD_ENABLE); /* Enable transmitter */ + LPUART_PDD_EnableReceiver(LPUART0_BASE_PTR, PDD_ENABLE); /* Enable receiver */ + LPUART_PDD_EnableInterrupt(LPUART0_BASE_PTR, ( LPUART_PDD_INTERRUPT_RECEIVER | LPUART_PDD_INTERRUPT_PARITY_ERROR | LPUART_PDD_INTERRUPT_FRAMING_ERROR | LPUART_PDD_INTERRUPT_NOISE_ERROR | LPUART_PDD_INTERRUPT_OVERRUN_ERROR )); /* Enable interrupts */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ASerialLdd1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} + +/* +** =================================================================== +** Method : ASerialLdd1_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the previous receive operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */ + DeviceDataPrv->InpDataNumReq = Size; /* Store a number of characters to be received. */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : ASerialLdd1_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->OutDataNumReq != 0x00U) { /* Is the previous transmit operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->OutDataPtr = (uint8_t*)BufferPtr; /* Set a pointer to the output data. */ + DeviceDataPrv->OutDataNumReq = Size; /* Set the counter of characters to be sent. */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters. */ + DeviceDataPrv->SerFlag |= ENABLED_TX_INT; /* Set the flag ENABLED_TX_INT */ + LPUART_PDD_EnableInterrupt(LPUART0_BASE_PTR, LPUART_PDD_INTERRUPT_TRANSMITTER); /* Enable TX interrupt */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : InterruptRx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptRx(ASerialLdd1_TDeviceDataPtr DeviceDataPrv) +{ + register uint16_t Data; /* Temporary variable for data */ + + Data = (uint16_t)LPUART_PDD_GetChar8(LPUART0_BASE_PTR); /* Read an 8-bit character from the receiver */ + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */ + *(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put an 8-bit character to the receive buffer */ + DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */ + if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */ + ASerialLdd1_OnBlockReceived(DeviceDataPrv->UserDataPtr); + } + } +} + +/* +** =================================================================== +** Method : InterruptTx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptTx(ASerialLdd1_TDeviceDataPtr DeviceDataPrv) +{ + + if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */ + LPUART_PDD_PutChar8(LPUART0_BASE_PTR, *(DeviceDataPrv->OutDataPtr++)); /* Put a 8-bit character to the transmit register */ + DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */ + if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) { + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + ASerialLdd1_OnBlockSent(DeviceDataPrv->UserDataPtr); + } + } else { + LPUART_PDD_DisableInterrupt(LPUART0_BASE_PTR, LPUART_PDD_INTERRUPT_TRANSMITTER); /* Disable TX interrupt */ + DeviceDataPrv->SerFlag &= (uint16_t)(~(uint16_t)ENABLED_TX_INT); /* Clear the flag ENABLED_TX_INT */ + } +} + +/* +** =================================================================== +** Method : ASerialLdd1_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(ASerialLdd1_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = INT_LPUART0__BAREBOARD_RTOS_ISRPARAM; + register uint32_t StatReg = LPUART_PDD_ReadInterruptStatusReg(LPUART0_BASE_PTR); /* Read status register */ + register uint16_t OnErrorFlags = 0U; /* Temporary variable for flags */ + register uint8_t OnBreakFlag = 0U; /* Temporary variable flag for OnBreak event */ + register uint16_t Data; /* Temporary variable for data */ + + if (StatReg & (LPUART_STAT_NF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)) { /* Is any error flag set? */ + LPUART_PDD_ClearInterruptFlags(LPUART0_BASE_PTR, (LPUART_STAT_NF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); + Data = (uint16_t)LPUART_PDD_GetChar8(LPUART0_BASE_PTR); /* Read an 8-bit character from receiver */ + if ((StatReg & LPUART_STAT_FE_MASK) != 0U) { /* Is the framing error detected? */ + if (((StatReg & LPUART_STAT_RDRF_MASK) != 0U) && (Data == 0U)) { /* Is the zero character in the receiver? */ + OnBreakFlag++; + DeviceDataPrv->SerFlag |= BREAK_DETECTED; /* If yes then set the flag */ + } else { + OnErrorFlags |= LDD_SERIAL_FRAMING_ERROR; /* If yes then set the flag */ + } + } + if ((StatReg & LPUART_STAT_OR_MASK) != 0U) { /* Is the overrun error flag set? */ + OnErrorFlags |= LDD_SERIAL_RX_OVERRUN; /* If yes then set the flag */ + } + if ((StatReg & LPUART_STAT_PF_MASK) != 0U) { /* Is the parity error flag set? */ + OnErrorFlags |= LDD_SERIAL_PARITY_ERROR; /* If yes then set the flag */ + } + if ((StatReg & LPUART_STAT_NF_MASK) != 0U) { /* Is the noise error flag set? */ + OnErrorFlags |= LDD_SERIAL_NOISE_ERROR; /* If yes then set the flag */ + } + DeviceDataPrv->ErrFlag |= OnErrorFlags; /* Copy flags status to ErrFlag status variable */ + StatReg &= (uint32_t)(~(uint32_t)LPUART_STAT_RDRF_MASK); /* Clear the receive data flag to discard the errorneous data */ + if (OnBreakFlag != 0U) { + ASerialLdd1_OnBreak(DeviceDataPrv->UserDataPtr); /* If yes then invoke user event */ + } else { + ASerialLdd1_OnError(DeviceDataPrv->UserDataPtr); /* Invoke user event */ + } + } + if (StatReg & LPUART_STAT_RDRF_MASK) { /* Is the receiver's interrupt flag set? */ + InterruptRx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + if (DeviceDataPrv->SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */ + if (StatReg & LPUART_STAT_TDRE_MASK) { /* Is the transmitter empty? */ + InterruptTx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + } +} + +/* +** =================================================================== +** Method : ASerialLdd1_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + *ErrorPtr = DeviceDataPrv->ErrFlag; + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/*lint -restore Enable MISRA rule (11.4,12.8) checking. */ +/* END ASerialLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.h new file mode 100644 index 0000000..1e6b579 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd1.h @@ -0,0 +1,337 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd1 +** Device : LPUART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_LPUART0 +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_LPUART0 +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_LPUART0 +** Interrupt Error priority : medium priority +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Transmitter : Enabled +** TxD : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd1.h +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd1_module ASerialLdd1 module documentation +** @{ +*/ + +#ifndef __ASerialLdd1_H +#define __ASerialLdd1_H + +/* MODULE ASerialLdd1. */ + + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define ASerialLdd1_PRPH_BASE_ADDRESS 0x4002A000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define ASerialLdd1_Init_METHOD_ENABLED /*!< Init method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_SendBlock_METHOD_ENABLED /*!< SendBlock method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_ReceiveBlock_METHOD_ENABLED /*!< ReceiveBlock method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_GetError_METHOD_ENABLED /*!< GetError method of the component ASerialLdd1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define ASerialLdd1_OnBlockReceived_EVENT_ENABLED /*!< OnBlockReceived event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnBlockSent_EVENT_ENABLED /*!< OnBlockSent event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnBreak_EVENT_ENABLED /*!< OnBreak event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnError_EVENT_ENABLED /*!< OnError event of the component ASerialLdd1 is enabled (generated) */ + +#define ENABLED_TX_INT 0x01U /*!< TX interrupt enabled */ +#define BREAK_DETECTED 0x02U /*!< Break detected */ +#define TX_COMPLETED 0x04U /*!< Transmission completed */ +#define ENABLE_TX_COMPLETE 0x10U /*!< Enable/Disable of TX complete detection. Used in the polling mode only */ + +/*! Device data structure type */ +typedef struct { + uint16_t SerFlag; /*!< Flags for serial communication */ + LDD_SERIAL_TError ErrFlag; /*!< Error flags mirror of SerFlag */ + uint16_t InpRecvDataNum; /*!< The counter of received characters */ + uint8_t *InpDataPtr; /*!< The buffer pointer for received characters */ + uint16_t InpDataNumReq; /*!< The counter of characters to receive by ReceiveBlock() */ + uint16_t OutSentDataNum; /*!< The counter of sent characters */ + uint8_t *OutDataPtr; /*!< The buffer pointer for data to be transmitted */ + uint16_t OutDataNumReq; /*!< The counter of characters to be send by SendBlock() */ + LDD_TUserData *UserDataPtr; /*!< Pointer to user data */ +} ASerialLdd1_TDeviceData; + +typedef ASerialLdd1_TDeviceData *ASerialLdd1_TDeviceDataPtr ; /*!< Pointer to the device data structure. */ + +/* +** =================================================================== +** Method : ASerialLdd1_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : ASerialLdd1_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd1_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd1_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(ASerialLdd1_Interrupt); + +/* +** =================================================================== +** Method : ASerialLdd1_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr); + +/* END ASerialLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __ASerialLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.c new file mode 100644 index 0000000..5600662 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.c @@ -0,0 +1,525 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd2.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd2 +** Device : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : medium priority +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Transmitter : Enabled +** TxD : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd2.c +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd2_module ASerialLdd2 module documentation +** @{ +*/ + +/* MODULE ASerialLdd2. */ +/*lint -save -e926 -e927 -e928 -e929 -e572 Disable MISRA rule (11.4,12.8) checking. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "ASerialLdd2.h" +#include "AS2.h" +#include "UART_PDD.h" +#include "SIM_PDD.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! The mask of available events used to enable/disable events during runtime. */ +#define AVAILABLE_EVENTS_MASK (LDD_SERIAL_ON_BLOCK_RECEIVED | LDD_SERIAL_ON_BLOCK_SENT | LDD_SERIAL_ON_BREAK | LDD_SERIAL_ON_ERROR) + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static ASerialLdd2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd2_TDeviceDataPtr INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd2_TDeviceDataPtr INT_UART0_ERR__BAREBOARD_RTOS_ISRPARAM; + +/* +** =================================================================== +** Method : ASerialLdd2_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + + /* Clear the receive counters and pointer */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ + DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ + /* Clear the transmit counters and pointer */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Allocate interrupt vectors */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART0_ERR__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC4: UART0=1 */ + SIM_SCGC4 |= SIM_SCGC4_UART0_MASK; + /* SIM_SCGC5: PORTB=1 */ + SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK; + /* PORTB_PCR16: ISF=0,MUX=3 */ + PORTB_PCR16 = (uint32_t)((PORTB_PCR16 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* PORTB_PCR17: ISF=0,MUX=3 */ + PORTB_PCR17 = (uint32_t)((PORTB_PCR17 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* NVICIP31: PRI31=0x70 */ + NVICIP31 = NVIC_IP_PRI31(0x70); + /* NVICISER0: SETENA|=0x80000000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x80000000); + /* NVICIP32: PRI32=0x70 */ + NVICIP32 = NVIC_IP_PRI32(0x70); + /* NVICISER1: SETENA|=1 */ + NVICISER1 |= NVIC_ISER_SETENA(0x01); + UART_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_DISABLE); /* Disable transmitter. */ + UART_PDD_EnableReceiver(UART0_BASE_PTR, PDD_DISABLE); /* Disable receiver. */ + DeviceDataPrv->SerFlag = 0x00U; /* Reset flags */ + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* UART0_C1: LOOPS=0,UARTSWAI=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */ + UART0_C1 = 0x00U; /* Set the C1 register */ + /* UART0_C3: R8=0,T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */ + UART0_C3 = 0x00U; /* Set the C3 register */ + /* UART0_C4: MAEN1=0,MAEN2=0,M10=0,BRFA=0 */ + UART0_C4 = UART_C4_BRFA(0x00); /* Set the C4 register */ + /* UART0_S2: LBKDIF=0,RXEDGIF=0,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */ + UART0_S2 = 0x00U; /* Set the S2 register */ + /* UART0_MODEM: ??=0,??=0,??=0,??=0,RXRTSE=0,TXRTSPOL=0,TXRTSE=0,TXCTSE=0 */ + UART0_MODEM = 0x00U; /* Set the MODEM register */ + UART_PDD_SetBaudRateFineAdjust(UART0_BASE_PTR, 10u); /* Set baud rate fine adjust */ + UART_PDD_SetBaudRate(UART0_BASE_PTR, 195U); /* Set the baud rate register. */ + UART_PDD_EnableFifo(UART0_BASE_PTR, (UART_PDD_TX_FIFO_ENABLE | UART_PDD_RX_FIFO_ENABLE)); /* Enable RX and TX FIFO */ + UART_PDD_FlushFifo(UART0_BASE_PTR, (UART_PDD_TX_FIFO_FLUSH | UART_PDD_RX_FIFO_FLUSH)); /* Flush RX and TX FIFO */ + UART_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_ENABLE); /* Enable transmitter */ + UART_PDD_EnableReceiver(UART0_BASE_PTR, PDD_ENABLE); /* Enable receiver */ + UART_PDD_EnableInterrupt(UART0_BASE_PTR, ( UART_PDD_INTERRUPT_RECEIVER | UART_PDD_INTERRUPT_PARITY_ERROR | UART_PDD_INTERRUPT_FRAMING_ERROR | UART_PDD_INTERRUPT_NOISE_ERROR | UART_PDD_INTERRUPT_OVERRUN_ERROR )); /* Enable interrupts */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ASerialLdd2_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} + +/* +** =================================================================== +** Method : ASerialLdd2_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the previous receive operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */ + DeviceDataPrv->InpDataNumReq = Size; /* Store a number of characters to be received. */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : ASerialLdd2_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->OutDataNumReq != 0x00U) { /* Is the previous transmit operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->OutDataPtr = (uint8_t*)BufferPtr; /* Set a pointer to the output data. */ + DeviceDataPrv->OutDataNumReq = Size; /* Set the counter of characters to be sent. */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters. */ + DeviceDataPrv->SerFlag |= ENABLED_TX_INT; /* Set the flag ENABLED_TX_INT */ + UART_PDD_EnableInterrupt(UART0_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Enable TX interrupt */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : InterruptRx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptRx(ASerialLdd2_TDeviceDataPtr DeviceDataPrv) +{ + register uint16_t Data; /* Temporary variable for data */ + + Data = (uint16_t)UART_PDD_GetChar8(UART0_BASE_PTR); /* Read an 8-bit character from the receiver */ + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */ + *(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put an 8-bit character to the receive buffer */ + DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */ + if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */ + ASerialLdd2_OnBlockReceived(DeviceDataPrv->UserDataPtr); + } + } +} + +/* +** =================================================================== +** Method : InterruptTx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptTx(ASerialLdd2_TDeviceDataPtr DeviceDataPrv) +{ + + if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */ + UART_PDD_PutChar8(UART0_BASE_PTR, *(DeviceDataPrv->OutDataPtr++)); /* Put a 8-bit character to the transmit register */ + DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */ + if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) { + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + ASerialLdd2_OnBlockSent(DeviceDataPrv->UserDataPtr); + } + } else { + UART_PDD_DisableInterrupt(UART0_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Disable TX interrupt */ + DeviceDataPrv->SerFlag &= (uint16_t)(~(uint16_t)ENABLED_TX_INT); /* Clear the flag ENABLED_TX_INT */ + } +} + +/* +** =================================================================== +** Method : ASerialLdd2_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(ASerialLdd2_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM; + register uint32_t StatReg = UART_PDD_ReadInterruptStatusReg(UART0_BASE_PTR); /* Read status register */ + register uint16_t OnErrorFlags = 0U; /* Temporary variable for flags */ + register uint8_t OnBreakFlag = 0U; /* Temporary variable flag for OnBreak event */ + register uint16_t Data; /* Temporary variable for data */ + + if (StatReg & (UART_S1_NF_MASK | UART_S1_OR_MASK | UART_S1_FE_MASK | UART_S1_PF_MASK)) { /* Is any error flag set? */ + Data = (uint16_t)UART_PDD_GetChar8(UART0_BASE_PTR); /* Read an 8-bit character from receiver */ + if ((StatReg & UART_S1_FE_MASK) != 0U) { /* Is the framing error detected? */ + if (((StatReg & UART_S1_RDRF_MASK) != 0U) && (Data == 0U)) { /* Is the zero character in the receiver? */ + OnBreakFlag++; + DeviceDataPrv->SerFlag |= BREAK_DETECTED; /* If yes then set the flag */ + } else { + OnErrorFlags |= LDD_SERIAL_FRAMING_ERROR; /* If yes then set the flag */ + } + } + if ((StatReg & UART_S1_OR_MASK) != 0U) { /* Is the overrun error flag set? */ + OnErrorFlags |= LDD_SERIAL_RX_OVERRUN; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_PF_MASK) != 0U) { /* Is the parity error flag set? */ + OnErrorFlags |= LDD_SERIAL_PARITY_ERROR; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_NF_MASK) != 0U) { /* Is the noise error flag set? */ + OnErrorFlags |= LDD_SERIAL_NOISE_ERROR; /* If yes then set the flag */ + } + DeviceDataPrv->ErrFlag |= OnErrorFlags; /* Copy flags status to ErrFlag status variable */ + StatReg &= (uint32_t)(~(uint32_t)UART_S1_RDRF_MASK); /* Clear the receive data flag to discard the errorneous data */ + if (OnBreakFlag != 0U) { + ASerialLdd2_OnBreak(DeviceDataPrv->UserDataPtr); /* If yes then invoke user event */ + } else { + ASerialLdd2_OnError(DeviceDataPrv->UserDataPtr); /* Invoke user event */ + } + } + if (StatReg & UART_S1_RDRF_MASK) { /* Is the receiver's interrupt flag set? */ + InterruptRx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + if (DeviceDataPrv->SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */ + if (StatReg & UART_S1_TDRE_MASK) { /* Is the transmitter empty? */ + InterruptTx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + } +} + +/* +** =================================================================== +** Method : ASerialLdd2_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + *ErrorPtr = DeviceDataPrv->ErrFlag; + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/*lint -restore Enable MISRA rule (11.4,12.8) checking. */ +/* END ASerialLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.h new file mode 100644 index 0000000..749e9e7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/ASerialLdd2.h @@ -0,0 +1,337 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd2.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd2 +** Device : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : medium priority +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : medium priority +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : medium priority +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Transmitter : Enabled +** TxD : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd2.h +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd2_module ASerialLdd2 module documentation +** @{ +*/ + +#ifndef __ASerialLdd2_H +#define __ASerialLdd2_H + +/* MODULE ASerialLdd2. */ + + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define ASerialLdd2_PRPH_BASE_ADDRESS 0x4006A000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define ASerialLdd2_Init_METHOD_ENABLED /*!< Init method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_SendBlock_METHOD_ENABLED /*!< SendBlock method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_ReceiveBlock_METHOD_ENABLED /*!< ReceiveBlock method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_GetError_METHOD_ENABLED /*!< GetError method of the component ASerialLdd2 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define ASerialLdd2_OnBlockReceived_EVENT_ENABLED /*!< OnBlockReceived event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnBlockSent_EVENT_ENABLED /*!< OnBlockSent event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnBreak_EVENT_ENABLED /*!< OnBreak event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnError_EVENT_ENABLED /*!< OnError event of the component ASerialLdd2 is enabled (generated) */ + +#define ENABLED_TX_INT 0x01U /*!< TX interrupt enabled */ +#define BREAK_DETECTED 0x02U /*!< Break detected */ +#define TX_COMPLETED 0x04U /*!< Transmission completed */ +#define ENABLE_TX_COMPLETE 0x10U /*!< Enable/Disable of TX complete detection. Used in the polling mode only */ + +/*! Device data structure type */ +typedef struct { + uint16_t SerFlag; /*!< Flags for serial communication */ + LDD_SERIAL_TError ErrFlag; /*!< Error flags mirror of SerFlag */ + uint16_t InpRecvDataNum; /*!< The counter of received characters */ + uint8_t *InpDataPtr; /*!< The buffer pointer for received characters */ + uint16_t InpDataNumReq; /*!< The counter of characters to receive by ReceiveBlock() */ + uint16_t OutSentDataNum; /*!< The counter of sent characters */ + uint8_t *OutDataPtr; /*!< The buffer pointer for data to be transmitted */ + uint16_t OutDataNumReq; /*!< The counter of characters to be send by SendBlock() */ + LDD_TUserData *UserDataPtr; /*!< Pointer to user data */ +} ASerialLdd2_TDeviceData; + +typedef ASerialLdd2_TDeviceData *ASerialLdd2_TDeviceDataPtr ; /*!< Pointer to the device data structure. */ + +/* +** =================================================================== +** Method : ASerialLdd2_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : ASerialLdd2_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd2_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd2_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(ASerialLdd2_Interrupt); + +/* +** =================================================================== +** Method : ASerialLdd2_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr); + +/* END ASerialLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __ASerialLdd2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.c new file mode 100644 index 0000000..8b900e1 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.c @@ -0,0 +1,254 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +/* MODULE BitIoLdd1. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd1_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd1_TDeviceData *BitIoLdd1_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd1_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Enable device clock gate */ + /* SIM_SCGC5: PORTC=1 */ + SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; + /* Configure pin as output */ + /* GPIOC_PDDR: PDD|=4 */ + GPIOC_PDDR |= GPIO_PDDR_PDD(0x04); + /* Set initialization value */ + /* GPIOC_PDOR: PDO&=~4 */ + GPIOC_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x04)); + /* Initialization of pin routing */ + /* PORTC_PCR2: ISF=0,MUX=1 */ + PORTC_PCR2 = (uint32_t)((PORTC_PCR2 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd1_MODULE_BASE_ADDRESS) & BitIoLdd1_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_TogglePortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.h new file mode 100644 index 0000000..c960e68 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/BitIoLdd1.h @@ -0,0 +1,235 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +#ifndef __BitIoLdd1_H +#define __BitIoLdd1_H + +/* MODULE BitIoLdd1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd1_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd1_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd1_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_NegVal_METHOD_ENABLED /*!< NegVal method of the component BitIoLdd1 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd1_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORT_MASK 0x04U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.c new file mode 100644 index 0000000..fa983ff --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.c @@ -0,0 +1,770 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CDC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FSL_USB_CDC_Device +** Version : Component 01.103, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** +** Settings : +** Component name : CDC1 +** Shell : CLS1 +** CPU : Kinetis K22FN120 +** CDC Settings : Enabled +** .inf ClassGuid : 4D36E978-E325-11CE-BFC1-08002BE10318 +** .inf VID : 0x2504 +** .inf PID : 0x0300 +** .inf PRVDR : Freescale +** .inf MFGNAME : My Company +** .inf DESCRIPTION : Freescale CDC Device +** .inf SERVICE : Virtual Com Driver +** Bus reported device : FSL CDC DEVICE +** Bus reported vendor : FREESCALE INC. +** Serial Number : 000123ABC +** Device Subclass : 0 +** Configuration : +** USB_EP0_SIZE (in) : 32 +** USB_EP1_SIZE (out) : 32 +** USB_EP2_SIZE (notify) : 32 +** Send Buffer : RingBuffer +** Receive Buffer : RingBuffer +** SendDataBlock : +** Use Timeout : Enabled +** Timeout : TMOUT1 +** App Task Timeout (ms) : 20 +** Waiting time (ms) : 10 +** Wait : WAIT1 +** Power Options : +** Bus Powered : yes +** Self Powered : yes +** Current Draw (mA) : 100 +** Contents : +** ClearRxBuffer - void CDC1_ClearRxBuffer(void); +** ClearTxBuffer - void CDC1_ClearTxBuffer(void); +** GetFreeInTxBuf - uint16_t CDC1_GetFreeInTxBuf(void); +** GetCharsInTxBuf - uint16_t CDC1_GetCharsInTxBuf(void); +** GetCharsInRxBuf - uint16_t CDC1_GetCharsInRxBuf(void); +** GetChar - uint8_t CDC1_GetChar(CDC1_TComData *Chr); +** RecvChar - uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +** SendChar - uint8_t CDC1_SendChar(CDC1_TComData Chr); +** SendString - uint8_t CDC1_SendString(CDC1_TComData *Chr); +** SendBlock - uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +** PutBufferChecked - uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +** App_Callback - void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** Notify_Callback - void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** ApplicationStarted - bool CDC1_ApplicationStarted(void); +** TransactionsStarted - bool CDC1_TransactionsStarted(void); +** App_Task - uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +** StdIOKeyPressed - bool CDC1_StdIOKeyPressed(void); +** StdIOReadChar - void CDC1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void CDC1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr CDC1_GetStdio(void); +** Deinit - uint8_t CDC1_Deinit(void); +** Init - uint8_t CDC1_Init(void); +** +** * Copyright : USB Stack sources (c) Copyright Freescale, all rights reserved, 2013-2017 +** * Adapted for Processor Expert: Erich Styger, 2015-2019 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** ###################################################################*/ +/*! +** @file CDC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CDC1_module CDC1 module documentation +** @{ +*/ + +/* MODULE CDC1. */ + +#include "CDC1.h" +#include "hidef.h" /* for EnableInterrupts macro */ +#include "derivative.h" /* include peripheral declarations */ +#include "types.h" /* Contains User Defined Data Types */ +#include "usb_cdc.h" /* USB CDC Class Header File */ +#include +/* skip the inclusion in dependency state */ +#ifndef __NO_SETJMP + #include +#endif +#include +#include +#if CDC1_CONFIG_USE_TIMEOUT + #include "TMOUT1.h" +#endif +#include "WAIT1.h" + +#define CONTROLLER_ID (0) /* ID to identify USB CONTROLLER */ + +#if HIGH_SPEED_DEVICE +static uint_32 g_cdcBuffer[DIC_BULK_OUT_ENDP_PACKET_SIZE>>1]; +#endif + +/* Virtual COM Application start Init Flag */ +static volatile boolean start_app = FALSE; + +/* Virtual COM Application Carrier Activate Flag */ +static volatile boolean start_transactions = FALSE; +static volatile boolean transactionOngoing = FALSE; + +/* default standard I/O struct */ +CLS1_ConstStdIOType CDC1_stdio = { + (CLS1_StdIO_In_FctType)CDC1_StdIOReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)CDC1_StdIOSendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)CDC1_StdIOSendChar, /* stderr */ + CDC1_StdIOKeyPressed /* if input is not empty */ + }; +uint8_t CDC1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +/* +** =================================================================== +** Method : GetFreeInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of free character in the send buffer +** Parameters : None +** Returns : +** --- - Number of free character in the receive +** buffer. +** =================================================================== +*/ +/* +uint16_t CDC1_GetFreeInTxBuf(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : GetCharsInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the send buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ +/* +uint16_t CDC1_GetCharsInTxBuf(void) +{ + *** implemented as macro in the header file + return (uint16_t)Tx1_NofElements(); +} +*/ + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the receive buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ +uint16_t CDC1_GetCharsInRxBuf(void) +{ + static uint8_t txBuf[CDC1_DATA_BUFF_SIZE]; + + if (CDC1_App_Task(txBuf, sizeof(txBuf))!=ERR_OK) { /* call USB handler: if active, then this will empty the buffer */ + } + return (uint16_t)Rx1_NofElements(); +} + +/* +** =================================================================== +** Method : GetChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is not +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ +/** +uint8_t CDC1_GetChar(CDC1_TComData *Chr) +{ + *** implemented as macro in the header file + return Rx1_Get(Chr); +} +*/ +/* +** =================================================================== +** Method : RecvChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ +uint8_t CDC1_RecvChar(CDC1_TComData *Chr) +{ + while(Rx1_Get(Chr)!=ERR_OK) { + WAIT1_WaitOSms(10); /* avoid to completely block */ + /* retry receiving until success */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendChar (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a character to the USB interface. Method is +** non-blocking: If the output buffer is full, it tries to send +** it over USB. If this fails or buffer is still full, the +** character will be lost. If OnError() event is enabled, the +** error event will be called in case of error. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendChar(CDC1_TComData Chr) +{ + static uint8_t txBuf[CDC1_DATA_BUFF_SIZE]; + uint8_t res; + + if (Tx1_Put(Chr)==ERR_TXFULL) { /* retry once, otherwise throw it away */ + res = CDC1_App_Task(txBuf, sizeof(txBuf)); /* call USB handler: if active, then this will empty the buffer */ + if (res==ERR_BUSOFF) { /* USB not enumerated */ + return ERR_FAILED; + } else if (res!=ERR_OK) { + return ERR_TXFULL; + } else { /* retry, as USB App_Task() should have sent the buffer */ + return Tx1_Put(Chr); /* retry. If buffer is still full, we will lose the character */ + } + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendBlock (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a data block to the USB interface. Method is +** non-blocking: if data cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to send. +** dataSize - Size of data in bytes +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize) +{ + uint8_t res = ERR_OK; + + while(dataSize > 0) { + if (CDC1_SendChar(*data)!=ERR_OK) { + res = ERR_TXFULL; + } + dataSize--; data++; + } + return res; +} + +/* +** =================================================================== +** Method : SendString (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a string to the USB interface. Method is +** non-blocking: if string cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to string to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ +uint8_t CDC1_SendString(CDC1_TComData *Chr) +{ + uint8_t res = ERR_OK; + + while(*Chr != '\0') { + if (CDC1_SendChar(*Chr)!=ERR_OK) { + res = ERR_TXFULL; + } + Chr++; + } + return res; +} + +/* +** =================================================================== +** Method : App_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle class callbacks from USB +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - gives the configuration value +** Returns : Nothing +** =================================================================== +*/ +void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val) +{ + UNUSED(controller_ID); + UNUSED(val); + if (event_type == USB_APP_BUS_RESET) { + start_app = FALSE; + } else if (event_type == USB_APP_ENUM_COMPLETE) { +#if HIGH_SPEED_DEVICE + /* prepare for the next receive event */ + USB_Class_CDC_Interface_DIC_Recv_Data(&controller_ID, + (uint_8_ptr)g_cdcBuffer, + DIC_BULK_OUT_ENDP_PACKET_SIZE); +#else + (void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); +#endif + start_app = TRUE; + } else if ((event_type==USB_APP_DATA_RECEIVED) && (start_transactions==TRUE)) { + /* Copy Received Data buffer to Application Buffer */ + USB_PACKET_SIZE BytesToBeCopied; + APP_DATA_STRUCT *dp_rcv = (APP_DATA_STRUCT*)val; + uint_8 idx; + + BytesToBeCopied = (USB_PACKET_SIZE)((dp_rcv->data_size>CDC1_DATA_BUFF_SIZE) ? CDC1_DATA_BUFF_SIZE:dp_rcv->data_size); + for(idx = 0; idxdata_ptr[idx])!=ERR_OK) { + /* Failed to put byte into buffer. Is the buffer to small? Then increase the Rx buffer. + Otherwise not much we could do here, so we are loosing byte here. + */ + /* Enable OnError() event so this event will be called here */ + } + } + (void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); /* see http://eprints.utar.edu.my/143/1/BI-2011-0708672-1.pdf, page 131 */ + } else if ((event_type==USB_APP_SEND_COMPLETE) && (start_transactions==TRUE)) { + transactionOngoing = FALSE; + /* Previous Send is complete. Queue next receive */ +#if HIGH_SPEED_DEVICE + //(void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, g_cdcBuffer, 0); +#else + //(void)USB_Class_CDC_Interface_DIC_Recv_Data(CONTROLLER_ID, NULL, 0); +#endif + } else if (event_type == USB_APP_ERROR) { /* detach? */ + start_app = FALSE; + start_transactions = FALSE; + } else if (event_type == USB_APP_BUS_SUSPEND) { /* disconnected cable? */ + start_app = FALSE; + start_transactions = FALSE; + } +} + +/* +** =================================================================== +** Method : Notify_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle PSTN Sub Class callbacks +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - +** Returns : Nothing +** =================================================================== +*/ +void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val) +{ + UNUSED(controller_ID); + UNUSED(val); + if (start_app == TRUE) { + if(event_type == USB_APP_CDC_CARRIER_ACTIVATED) { + start_transactions = TRUE; + } else if(event_type == USB_APP_CDC_CARRIER_DEACTIVATED) { + start_transactions = FALSE; + } + } +#if 1 /* not needed any more? see https://community.freescale.com/message/605537?et=watches.email.thread# */ + start_transactions = TRUE; /* ??? see http://forums.freescale.com/t5/Freescale-MQX-trade-USB-Host/Cant-get-CDC-virtual-com-demo-to-work-with-VB2005-on-xp-sp3/m-p/92713#M302 */ +#endif +} + +/* +** =================================================================== +** Method : CDC1_RunUsbEngine (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void CDC1_RunUsbEngine(void) +{ + /* not needed */ +} + +/* +** =================================================================== +** Method : CDC1_SendDataBlock (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +uint8_t CDC1_SendDataBlock(uint8_t *data, size_t dataSize) +{ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + TMOUT1_CounterHandle timeout; +#endif + uint8_t res = ERR_OK; + + transactionOngoing = TRUE; + if (USB_Class_CDC_Interface_DIC_Send_Data(CONTROLLER_ID, data, dataSize)!=USB_OK) { + transactionOngoing = FALSE; + return ERR_FAULT; + } + /* wait for transaction finish */ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + timeout = TMOUT1_GetCounter(CDC1_CONFIG_APP_TASK_TIMEOUT_MS/TMOUT1_TICK_PERIOD_MS); /* set up timeout counter */ +#endif + while(transactionOngoing) { /* wait until transaction is finished */ + /*lint -save -e522 function lacks side-effects */ + CDC1_RunUsbEngine(); + /*lint -restore */ +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + if (TMOUT1_CounterExpired(timeout)) { + res = ERR_FAILED; + break; + } +#endif + WAIT1_WaitOSms(10); /* wait some time */ + } +#if CDC1_CONFIG_USE_TIMEOUT && CDC1_CONFIG_APP_TASK_TIMEOUT_MS>0 + TMOUT1_LeaveCounter(timeout); /* return timeout counter */ +#endif + return res; +} + +/* +** =================================================================== +** Method : App_Task (component FSL_USB_CDC_Device) +** +** Description : +** Application task to be called periodically from the main +** task. +** Parameters : +** NAME - DESCRIPTION +** * txBuf - Pointer to temporary buffer used to +** transmit data over USB. Should be equal or +** greater than the endpoint buffer size. Data +** will be sent in an asynchronous way, so +** make sure the buffer is *not* on the stack. +** This buffer must be available until the +** next transmission. +** txBufSize - Size of the buffer in bytes +** Returns : +** --- - Error code, returns ERR_OK if USB +** enumeration has been finished, error code +** otherwise. +** =================================================================== +*/ +uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize) +{ + size_t i; + uint8_t res; + + /* device is Kinetis K22FN120 */ + /*lint -save -e522 function lacks side-effects */ + CDC1_RunUsbEngine(); + /*lint -restore */ + /* call the periodic task function */ + USB_Class_CDC_Periodic_Task(); + /* check whether enumeration is complete or not */ + if ((start_app==TRUE) && (start_transactions==TRUE)) { + if (Tx1_NofElements()!=0) { + i = 0; + while(iCDC1_GetFreeInTxBuf()) { /* no room at the Inn... */ + res = ERR_TXFULL; + } else { + res = ERR_OK; + while(bufSize>0 && res==ERR_OK) { + res = Tx1_Put(*buf); + bufSize--; + buf++; + } + } + return res; +} + +/* +** =================================================================== +** Method : ClearRxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the receiver buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void CDC1_ClearRxBuffer(void) +{ + Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ClearTxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the transmit buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void CDC1_ClearTxBuffer(void) +{ + Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : StdIOKeyPressed (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in the +** input/RX buffer +** =================================================================== +*/ +bool CDC1_StdIOKeyPressed(void) +{ + return (bool)((CDC1_GetCharsInRxBuf()==0U) ? FALSE : TRUE); /* true if there are characters in receive buffer */ +} + +/* +** =================================================================== +** Method : StdIOReadChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ +void CDC1_StdIOReadChar(uint8_t *c) +{ + if (CDC1_RecvChar((uint8_t *)c) != ERR_OK) { + /* failed to receive character: return a zero character */ + *c = '\0'; + } +} + +/* +** =================================================================== +** Method : StdIOSendChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send. +** Returns : Nothing +** =================================================================== +*/ +void CDC1_StdIOSendChar(uint8_t ch) +{ + while (CDC1_SendChar((uint8_t)ch)==ERR_TXFULL){} /* Send char */ +} + +/* +** =================================================================== +** Method : ApplicationStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if the CDC application has been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CDC1_ApplicationStarted(void) +{ + return start_app; /* TRUE if CDC is running */ +} + +/* +** =================================================================== +** Method : TransactionsStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if USB transactions have been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CDC1_TransactionsStarted(void) +{ + return start_transactions; /* port open on host */ +} + +/* +** =================================================================== +** Method : GetStdio (component FSL_USB_CDC_Device) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr CDC1_GetStdio(void) +{ + return &CDC1_stdio; +} + +/* END CDC1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.h new file mode 100644 index 0000000..c5ab366 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1.h @@ -0,0 +1,502 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CDC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FSL_USB_CDC_Device +** Version : Component 01.103, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** +** Settings : +** Component name : CDC1 +** Shell : CLS1 +** CPU : Kinetis K22FN120 +** CDC Settings : Enabled +** .inf ClassGuid : 4D36E978-E325-11CE-BFC1-08002BE10318 +** .inf VID : 0x2504 +** .inf PID : 0x0300 +** .inf PRVDR : Freescale +** .inf MFGNAME : My Company +** .inf DESCRIPTION : Freescale CDC Device +** .inf SERVICE : Virtual Com Driver +** Bus reported device : FSL CDC DEVICE +** Bus reported vendor : FREESCALE INC. +** Serial Number : 000123ABC +** Device Subclass : 0 +** Configuration : +** USB_EP0_SIZE (in) : 32 +** USB_EP1_SIZE (out) : 32 +** USB_EP2_SIZE (notify) : 32 +** Send Buffer : RingBuffer +** Receive Buffer : RingBuffer +** SendDataBlock : +** Use Timeout : Enabled +** Timeout : TMOUT1 +** App Task Timeout (ms) : 20 +** Waiting time (ms) : 10 +** Wait : WAIT1 +** Power Options : +** Bus Powered : yes +** Self Powered : yes +** Current Draw (mA) : 100 +** Contents : +** ClearRxBuffer - void CDC1_ClearRxBuffer(void); +** ClearTxBuffer - void CDC1_ClearTxBuffer(void); +** GetFreeInTxBuf - uint16_t CDC1_GetFreeInTxBuf(void); +** GetCharsInTxBuf - uint16_t CDC1_GetCharsInTxBuf(void); +** GetCharsInRxBuf - uint16_t CDC1_GetCharsInRxBuf(void); +** GetChar - uint8_t CDC1_GetChar(CDC1_TComData *Chr); +** RecvChar - uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +** SendChar - uint8_t CDC1_SendChar(CDC1_TComData Chr); +** SendString - uint8_t CDC1_SendString(CDC1_TComData *Chr); +** SendBlock - uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +** PutBufferChecked - uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +** App_Callback - void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** Notify_Callback - void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +** ApplicationStarted - bool CDC1_ApplicationStarted(void); +** TransactionsStarted - bool CDC1_TransactionsStarted(void); +** App_Task - uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +** StdIOKeyPressed - bool CDC1_StdIOKeyPressed(void); +** StdIOReadChar - void CDC1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void CDC1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr CDC1_GetStdio(void); +** Deinit - uint8_t CDC1_Deinit(void); +** Init - uint8_t CDC1_Init(void); +** +** * Copyright : USB Stack sources (c) Copyright Freescale, all rights reserved, 2013-2017 +** * Adapted for Processor Expert: Erich Styger, 2015-2019 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** ###################################################################*/ +/*! +** @file CDC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CDC1_module CDC1 module documentation +** @{ +*/ + +#ifndef __CDC1_H +#define __CDC1_H + +/* MODULE CDC1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CDC1config.h" /* configuration */ + +#include /* for size_t */ +#include "CLS1.h" /* shell interface */ +#include "Rx1.h" +#include "Tx1.h" + + +#ifndef __BWUserType_CDC1_TComData +#define __BWUserType_CDC1_TComData + typedef uint8_t CDC1_TComData ; /* User type for communication data type. */ +#endif + +/* + DATA_BUFF_SIZE should be greater than or equal to the endpoint buffer size, + otherwise there will be data loss. For MC9S08JS16, maximum DATA_BUFF_SIZE + supported is 16 Bytes +*/ +#define CDC1_DATA_BUFF_SIZE CDC1_CONFIG_DATA_BUF_SIZE + +#define CDC1_USB_ERR_SEND 1 /* Error while sending */ +#define CDC1_USB_ERR_BUSOFF 2 /* Bus not ready */ +#define CDC1_USB_ERR_INIT 3 /* USB initialization error */ +#define CDC1_USB_ERR_TX_CHAR 4 /* Error sending character */ +#define CDC1_USB_ERR_TX_STRING 5 /* Error sending string */ +#define CDC1_USB_ERR_CHECKED_TXFULL 6 /* Error during sending a checked block */ +#define CDC1_USB_ERR_RECEIVE 7 /* Error while starting an receive transaction */ +#define CDC1_USB_ERR_RX_PUT 8 /* Error while putting RX byte into buffer */ +#define CDC1_USB_ERR_TX_BLOCK 9 /* Error sending data block */ +#define CDC1_USB_TIMEOUT_SEND 10 /* Timeout while sending */ +#define CDC1_USB_ERR_DEINIT 11 /* USB deinitialization error */ + +extern CLS1_ConstStdIOType CDC1_stdio; /* default standard I/O */ +extern uint8_t CDC1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +#define CDC1_GetFreeInTxBuf() \ + Tx1_NofFreeElements() +/* +** =================================================================== +** Method : GetFreeInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of free character in the send buffer +** Parameters : None +** Returns : +** --- - Number of free character in the receive +** buffer. +** =================================================================== +*/ + +uint8_t CDC1_RecvChar(CDC1_TComData *Chr); +/* +** =================================================================== +** Method : RecvChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ + +uint8_t CDC1_SendChar(CDC1_TComData Chr); +/* +** =================================================================== +** Method : SendChar (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a character to the USB interface. Method is +** non-blocking: If the output buffer is full, it tries to send +** it over USB. If this fails or buffer is still full, the +** character will be lost. If OnError() event is enabled, the +** error event will be called in case of error. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +#define CDC1_GetCharsInTxBuf() \ + Tx1_NofElements() +/* +** =================================================================== +** Method : GetCharsInTxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the send buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ + +uint16_t CDC1_GetCharsInRxBuf(void); +/* +** =================================================================== +** Method : GetCharsInRxBuf (component FSL_USB_CDC_Device) +** +** Description : +** Returns the number of character in the receive buffer +** Parameters : None +** Returns : +** --- - Number of character in the receive buffer. +** =================================================================== +*/ + +uint8_t CDC1_Init(void); +/* +** =================================================================== +** Method : Init (component FSL_USB_CDC_Device) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CDC1_App_Task(uint8_t *txBuf, size_t txBufSize); +/* +** =================================================================== +** Method : App_Task (component FSL_USB_CDC_Device) +** +** Description : +** Application task to be called periodically from the main +** task. +** Parameters : +** NAME - DESCRIPTION +** * txBuf - Pointer to temporary buffer used to +** transmit data over USB. Should be equal or +** greater than the endpoint buffer size. Data +** will be sent in an asynchronous way, so +** make sure the buffer is *not* on the stack. +** This buffer must be available until the +** next transmission. +** txBufSize - Size of the buffer in bytes +** Returns : +** --- - Error code, returns ERR_OK if USB +** enumeration has been finished, error code +** otherwise. +** =================================================================== +*/ + +uint8_t CDC1_SendString(CDC1_TComData *Chr); +/* +** =================================================================== +** Method : SendString (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a string to the USB interface. Method is +** non-blocking: if string cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to string to send. +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +#define CDC1_GetChar(Chr) \ + Rx1_Get(Chr) + +/* +** =================================================================== +** Method : GetChar (component FSL_USB_CDC_Device) +** +** Description : +** Receives a character from the USB interface. Function is not +** blocking if there is no character in the input buffer. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to where to store the character +** received +** Returns : +** --- - Error code, ERR_OK for success, +** ERR_RXEMPTY if nothing is in RX buffer. +** =================================================================== +*/ + +uint8_t CDC1_PutBufferChecked(uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : PutBufferChecked (component FSL_USB_CDC_Device) +** +** Description : +** Puts a data block into the output buffer, but does not send +** it. If there is not enough size available, then ERR_TXFULL +** is returned, otherwise ERR_OK. The application then needs to +** call USB_App_Callback() to actually send the buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be sent +** bufsize - Buffer size in bytes +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CDC1_App_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +/* +** =================================================================== +** Method : App_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle class callbacks from USB +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - gives the configuration value +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_Notify_Callback(uint8_t controller_ID, uint8_t event_type, void *val); +/* +** =================================================================== +** Method : Notify_Callback (component FSL_USB_CDC_Device) +** +** Description : +** Method to handle PSTN Sub Class callbacks +** Parameters : +** NAME - DESCRIPTION +** controller_ID - controller ID +** event_type - value of the event +** val - +** Returns : Nothing +** =================================================================== +*/ + +#define CDC1_ClearRxBuffer() \ + Rx1_Clear() +/* +** =================================================================== +** Method : ClearRxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the receiver buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define CDC1_ClearTxBuffer() \ + Tx1_Clear() +/* +** =================================================================== +** Method : ClearTxBuffer (component FSL_USB_CDC_Device) +** +** Description : +** Clears the transmit buffer content +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_RunUsbEngine(void); +/* +** =================================================================== +** Method : CDC1_RunUsbEngine (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t CDC1_SendBlock(uint8_t *data, size_t dataSize); +/* +** =================================================================== +** Method : SendBlock (component FSL_USB_CDC_Device) +** +** Description : +** Method to send a data block to the USB interface. Method is +** non-blocking: if data cannot be sent, it will be lost. If +** OnError() event is enabled, the error event will be called +** in case of error. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to send. +** dataSize - Size of data in bytes +** Returns : +** --- - Error code. ERR_OK for success and +** ERR_FAILED otherwise. +** =================================================================== +*/ + +uint8_t CDC1_SendDataBlock(uint8_t *data, size_t dataSize); +/* +** =================================================================== +** Method : CDC1_SendDataBlock (component FSL_USB_CDC_Device) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t CDC1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FSL_USB_CDC_Device) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool CDC1_StdIOKeyPressed(void); +/* +** =================================================================== +** Method : StdIOKeyPressed (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in the +** input/RX buffer +** =================================================================== +*/ + +void CDC1_StdIOReadChar(uint8_t *c); +/* +** =================================================================== +** Method : StdIOReadChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ + +void CDC1_StdIOSendChar(uint8_t ch); +/* +** =================================================================== +** Method : StdIOSendChar (component FSL_USB_CDC_Device) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send. +** Returns : Nothing +** =================================================================== +*/ + +bool CDC1_ApplicationStarted(void); +/* +** =================================================================== +** Method : ApplicationStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if the CDC application has been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool CDC1_TransactionsStarted(void); +/* +** =================================================================== +** Method : TransactionsStarted (component FSL_USB_CDC_Device) +** +** Description : +** Returns true if USB transactions have been started. +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr CDC1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component FSL_USB_CDC_Device) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END CDC1. */ + +#endif +/* ifndef __CDC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1config.h new file mode 100644 index 0000000..4979fce --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CDC1config.h @@ -0,0 +1,20 @@ +#ifndef __CDC1_CONFIG_H +#define __CDC1_CONFIG_H + +#ifndef CDC1_CONFIG_USE_TIMEOUT + #define CDC1_CONFIG_USE_TIMEOUT 1 + /*!< 1: Use timeout; 0: do not use timeout */ +#endif + +#ifndef CDC1_CONFIG_APP_TASK_TIMEOUT_MS + #define CDC1_CONFIG_APP_TASK_TIMEOUT_MS 20 + /*!< App Task timeout in milliseconds, 0 to disable timout */ +#endif + +#ifndef CDC1_CONFIG_DATA_BUF_SIZE + #define CDC1_CONFIG_DATA_BUF_SIZE (64) + /*!< Value used for CDC1_DATA_BUF_SIZE, must be a multiple of endpoint size. The greater the value, the better the performance */ +#endif + + +#endif /* __CDC1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.c new file mode 100644 index 0000000..6a17bb0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.c @@ -0,0 +1,1488 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:34, # CodeGen: 8 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD> " +** Project Name : tinyK22 OpenPnP +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Enabled +** Length : 32 +** Separator : ; +** Utility : UTIL1 +** Default Serial : Disabled +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + +/* MODULE CLS1. */ +#include /* for isalnum*/ + +#include "CLS1.h" +#include "XF1.h" +#include "UTIL1.h" +#include "CS1.h" + #include "WAIT1.h" + +#if CLS1_DEFAULT_SERIAL + #include CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE +#endif + + +uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +#if CLS1_HISTORY_ENABLED + static uint8_t CLS1_history[CLS1_NOF_HISTORY][CLS1_HIST_LEN]; /* History buffers */ + static uint8_t CLS1_history_index = 0; /* Selected command */ +#endif +#if CLS1_ECHO_ENABLED + static bool CLS1_EchoEnabled = TRUE; +#endif + +#if CLS1_CONFIG_USE_MUTEX + #include "FreeRTOS.h" + #include "task.h" + #include "semphr.h" +#endif + +#ifdef __HC08__ + #pragma MESSAGE DISABLE C3303 /* implicit concatenation of strings */ +#endif +#if CLS1_CONFIG_USE_MUTEX + static SemaphoreHandle_t ShellSem = NULL; /* Semaphore to protect shell SCI access */ +#endif + +#if CLS1_DEFAULT_SERIAL + CLS1_ConstStdIOType CLS1_stdio = + { + (CLS1_StdIO_In_FctType)CLS1_ReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stderr */ + CLS1_KeyPressed /* if input is not empty */ + }; + static CLS1_ConstStdIOType *CLS1_currStdIO = &CLS1_stdio; +#else + static CLS1_ConstStdIOType *CLS1_currStdIO = NULL; /* needs to be set through CLS1_SetStdio(); */ +#endif +/* Internal method prototypes */ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io); + +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + io(ch); +} + +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +/*! + * \brief Prints a string using I/O callbacks + * \param[in] str String (zero terminated) to be printed + * \param[in] io I/O function to be used for printing + */ +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + while(*str!='\0') { + io(*str++); + } +} + +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-1234567890")]; + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("1234567890")]; + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-12345")]; + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("12345")]; + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("123")]; + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-123")]; + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io) +{ + if (UTIL1_strcmp((char*)cmd, CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, "CLS1 help")==0) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROJECT_NAME_STRING, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)"CLS1", (const unsigned char*)"Group of CLS1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (const unsigned char*)"Print help or status information\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendHelpStr((unsigned char*)" echo (on|off)", (const unsigned char*)"Turn echo on or off\r\n", io->stdOut); +#endif + *handled = TRUE; + return ERR_OK; +#if CLS1_ECHO_ENABLED + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo on")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = TRUE; + return ERR_OK; + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo off")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = FALSE; + return ERR_OK; +#endif + } else if ((UTIL1_strcmp((char*)cmd, CLS1_CMD_STATUS)==0) || (UTIL1_strcmp((char*)cmd, "CLS1 status")==0)) { + *handled = TRUE; + return CLS1_PrintStatus(io); + } + return ERR_OK; /* no error */ +} + +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); /* ensure that there is a new line */ + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROMPT_STRING, io->stdOut); +} + +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev) +{ + *isPrev = FALSE; +#if CLS1_HISTORY_ENABLED + if ( cmdBufIdx==0 /* first character on command line */ + || (UTIL1_strcmp((const char*)cmdBuf, (const char*)CLS1_history[CLS1_history_index])==0) /* pressing prev/next character on previous history element */ + ) + { + if (ch==CLS1_HISTORY_PREV_CHAR) { + *isPrev = TRUE; + return TRUE; + } else if (ch==CLS1_HISTORY_NEXT_CHAR) { + *isPrev = FALSE; + return TRUE; + } + } +#if 0 + if (cmdBufIdx==0 || cmdBufIdx==2) { /* accept only first character or sequence as history sequence */ + if (cmdBufIdx==2 && cmdBuf[0]==0x1b && cmdBuf[1]==0x5b) { + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (cmdBuf[2]==0x41 /* up */ || cmdBuf[2]==0x44 /* left */) { + *isPrev = TRUE; + return TRUE; + } else if (cmdBuf[2]==0x42 /* down */ || cmdBuf[2]==0x43 /* right */) { + *isPrev = FALSE; + return TRUE; + } + } + /* \todo: handle TAB and SHIFT-TAB */ + } +#endif +#else + (void)ch; /* not used */ + (void)cmdBuf; /* not used */ + (void)cmdBufIdx; /* not used */ +#endif + return FALSE; +} + +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io) +{ + uint8_t c; + bool isBackwardHistory; + + if (io->keyPressed()) { + for(;;) { /* while not '\r' or '\n' */ + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + if (c=='\0') { /* nothing in rx buffer? Something is wrong... */ + break; /* get out of loop */ + } + if (c=='\b' || c=='\177') { /* check for backspace */ + if (buf > bufStart) { /* Avoid buffer underflow */ +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut('\b'); /* delete character on terminal */ + io->stdOut(' '); + io->stdOut('\b'); + } +#endif + buf--; /* delete last character in buffer */ + *buf = '\0'; + bufSize++; + } + } else if (CLS1_IsHistoryCharacter(c, bufStart, (size_t)(buf-bufStart), &isBackwardHistory)) { +#if CLS1_HISTORY_ENABLED + uint8_t cBuf[3]={'\0','\0','\0'}, cBufIdx = 0; + bool prevInHistory; +#endif + + while (c!='\0') { /* empty the rx buffer (escape sequence) */ +#if CLS1_HISTORY_ENABLED + cBuf[cBufIdx] = c; + cBufIdx++; + if (cBufIdx==sizeof(cBuf)) { + cBufIdx = 0; /* ring buffer */ + } +#endif + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + } +#if CLS1_HISTORY_ENABLED + /* if not an alphanumeric switch to history */ + prevInHistory = cBufIdx==0 && cBuf[0]==0x1b && cBuf[1]==0x5b && (cBuf[2]==0x41 /*up*/ || cBuf[2]==0x44 /*left*/); + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (prevInHistory) { + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + CLS1_history_index++; /* update the index */ + if (CLS1_history_index==CLS1_NOF_HISTORY) { + CLS1_history_index = 0; + } + } else { + if (CLS1_history_index==0) { + CLS1_history_index = (CLS1_NOF_HISTORY-1); + } else { + CLS1_history_index--; + } + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + } + bufSize = bufSize + buf - bufStart - UTIL1_strlen((const char*)bufStart); /* update the buffer */ + buf = bufStart + UTIL1_strlen((const char*)bufStart); +#endif +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_PrintPrompt(io); + CLS1_SendStr(bufStart, io->stdOut); + } +#endif + } else { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut(c); /* echo character */ + } +#endif + *buf = (uint8_t)c; /* append character to the string */ + buf++; + bufSize--; + if ((c=='\r') || (c=='\n')) { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\n", io->stdOut); + } +#endif +#if CLS1_HISTORY_ENABLED + if ((bufStart[0] != '\0') && (bufStart[0] != '\r') && (bufStart[0] != '\n')) { + int i; + + for(i=CLS1_NOF_HISTORY-1; i>0;i--) { + UTIL1_strcpy(CLS1_history[i], CLS1_HIST_LEN, CLS1_history[i-1]); /* move previous commands */ + } + CLS1_history_index = 0; /* update the history with the current command */ + UTIL1_strcpy(CLS1_history[0], CLS1_HIST_LEN, bufStart); /* add the current command to the history */ + if (buf-bufStart <= CLS1_HIST_LEN) { /* size check */ + CLS1_history[0][buf-bufStart-1] = '\0'; + } else { + CLS1_history[0][CLS1_HIST_LEN-1] = '\0'; + } + } +#endif + break; + } + if (bufSize <= 1) { /* buffer full */ + break; + } + } + } /* for */ + *buf = '\0'; /* zero terminate string */ + return TRUE; + } else { + return FALSE; + } +} + +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io) +{ + CLS1_SendStatusStr((const unsigned char*)"CLS1", (const unsigned char*)"\r\n", io->stdOut); + CLS1_SendStatusStr((const unsigned char*)" Build", (const unsigned char*)__DATE__, io->stdOut); + CLS1_SendStr((unsigned char*)" ", io->stdOut); + CLS1_SendStr((unsigned char*)__TIME__, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendStatusStr((const unsigned char*)" echo", CLS1_EchoEnabled?(const unsigned char*)"On\r\n":(const unsigned char*)"Off\r\n", io->stdOut); +#endif + return ERR_OK; +} + +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"*** Failed or unknown command: ", io->stdErr); + CLS1_SendStr(cmd, io->stdErr); + CLS1_SendStr((unsigned char*)"\r\n", io->stdErr); + CLS1_SendStr((unsigned char*)"*** Type ", io->stdErr); + CLS1_SendStr((unsigned char*)CLS1_CMD_HELP, io->stdErr); + CLS1_SendStr((unsigned char*)" to get a list of available commands\r\n", io->stdErr); +} + +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable) +{ + uint8_t res = ERR_OK; + + if (parserTable==NULL) { /* no table??? */ + return ERR_FAILED; + } + if (io==NULL) { /* no IO handler??? */ + return ERR_FAILED; + } + /* iterate through all parser functions in table */ + while(*parserTable!=NULL) { + if ((*parserTable)(cmd, handled, io)!=ERR_OK) { + res = ERR_FAILED; + } + parserTable++; + } + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + uint8_t res = ERR_OK; + bool handled; +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + bool silentPrefix = FALSE; +#endif +#if CLS1_CONFIG_MULTI_CMD_ENABLED + uint8_t buf[CLS1_CONFIG_MULTI_CMD_SIZE]; + uint8_t i; + bool parseBuffer, finished; +#endif + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + if (*cmd=='\0') { /* empty command */ + return ERR_OK; + } +#if CLS1_CONFIG_MULTI_CMD_ENABLED + parseBuffer = FALSE; + finished = FALSE; + i = 0; + for(;;) { /* breaks */ + if (i>sizeof(buf)-2) { + res = ERR_FAILED; + CLS1_PrintCommandFailed(buf, io); + break; /* buffer overflow */ + } + buf[i] = *cmd; + cmd++; i++; + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (i==1 && buf[0]==CLS1_SILENT_PREFIX_CHAR) { /* first character is silent character */ + silentPrefix |= (bool)(buf[0]==CLS1_SILENT_PREFIX_CHAR); + buf[0] = *cmd; /* skip silent character */ + cmd++; + } + #endif + if (buf[i-1] == CLS1_CONFIG_MULTI_CMD_CHAR) { /* found separator */ + buf[i-1] = '\0'; + parseBuffer = TRUE; + } else if (buf[i-1]=='\0') { + parseBuffer = TRUE; + finished = TRUE; + } + if (parseBuffer) { + handled = FALSE; + res = CLS1_IterateTable(buf, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command, or error? */ + CLS1_PrintCommandFailed(buf, io); + res = ERR_FAILED; + } + parseBuffer = FALSE; + i = 0; /* restart */ + } + if (finished) { + break; /* get out of loop */ + } + } /* for */ +#else + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + silentPrefix = (bool)(*cmd==CLS1_SILENT_PREFIX_CHAR); + if (silentPrefix) { + cmd++; /* skip silent character */ + } + #endif + handled = FALSE; + res = CLS1_IterateTable(cmd, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command? */ + CLS1_PrintCommandFailed(cmd, io); + res = ERR_FAILED; + } +#endif +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (!silentPrefix && !silent) { + CLS1_PrintPrompt(io); + } +#else + if (!silent) { + CLS1_PrintPrompt(io); + } +#endif + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ParseWithCommandTableExt(cmd, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio) +{ + CLS1_currStdIO = stdio; + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void) +{ + return CLS1_currStdIO; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + /* IMPORTANT NOTE: this function *appends* to the buffer, so the buffer needs to be initialized first! */ + uint8_t res = ERR_OK; + size_t len; + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + len = UTIL1_strlen((const char*)cmdBuf); + if (CLS1_ReadLine(cmdBuf, cmdBuf+len, cmdBufSize-len, io)) { + len = UTIL1_strlen((const char*)cmdBuf); /* length of buffer string */ + if (len==0) { /* error case */ + return ERR_FAILED; + } else if (len==1 && (cmdBuf[0]=='\n' || cmdBuf[0]=='\r')) { /* eat preceding newline characters */ + cmdBuf[0] = '\0'; + } + if (len>=cmdBufSize-1) { /* buffer overflow? Parse what we have, will be likely return an error */ + (void)CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + res = ERR_OVERFLOW; + } else if (cmdBuf[len-1]=='\n' || cmdBuf[len-1]=='\r') { /* line end: parse command */ + cmdBuf[len-1] = '\0'; /* remove line end character for parser */ + res = CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + } else { + /* continue to append to buffer */ + } + } + return res; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ReadAndParseWithCommandTableExt(cmdBuf, cmdBufSize, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_RequestSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +} + +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReleaseSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ +void* CLS1_GetSemaphore(void) +{ +#if CLS1_CONFIG_USE_MUTEX + return ShellSem; +#else + return NULL; +#endif +} + +/* +** =================================================================== +** Method : SendSeparatedStrings (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io) +{ + /* write command part */ + if (strA!=NULL) { + while(*strA!='\0' && tabPos>0) { + io(*strA++); + tabPos--; + } + } + /* fill up until ';' */ + while(tabPos>0) { + io(' '); + tabPos--; + } + /* write separator */ + io(tabChar); + io(' '); + if (strB!=NULL) { + /* write help text */ + CLS1_SendStr(strB, io); + } +} + +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io) +{ + #define HELP_SEMICOLON_POS 26 /* position of the ';' after the command string */ + SendSeparatedStrings(strCmd, strHelp, ';', HELP_SEMICOLON_POS, io); +} + +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io) +{ + #define STATUS_COLON_POS 13 /* position of the ':' after the item string */ + SendSeparatedStrings(strItem, strStatus, ':', STATUS_COLON_POS, io); +} + +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReadChar(uint8_t *c) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + uint8_t res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif + res = CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME((uint8_t*)c); + if (res==ERR_RXEMPTY) { + /* no character in buffer */ + *c = '\0'; + } +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +#else + *c = '\0'; + return; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendChar(uint8_t ch) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + CLS1_SendCharFct(ch, CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME); +#else + (void)ch; /* avoid compiler warning about unused argument */ +#endif +} + +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CLS1_KeyPressed(void) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + bool res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_DEFAULT_SERIAL + res = (bool)((CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME()==0U) ? FALSE : TRUE); /* true if there are characters in receive buffer */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif + return res; +#else + return FALSE; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_Init(void) +{ +#if CLS1_CONFIG_USE_MUTEX +#if configSUPPORT_STATIC_ALLOCATION + static StaticSemaphore_t xMutexBuffer; +#endif + bool schedulerStarted; + CS1_CriticalVariable(); + + schedulerStarted = (bool)(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED); + if (!schedulerStarted) { /* FreeRTOS not started yet. We are called in PE_low_level_init(), and interrupts are disabled */ + CS1_EnterCritical(); + } +#if configSUPPORT_STATIC_ALLOCATION + ShellSem = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer); +#else + ShellSem = xSemaphoreCreateRecursiveMutex(); +#endif + if (!schedulerStarted) { /* above RTOS call might have enabled interrupts! Make sure we restore the state */ + CS1_ExitCritical(); + } + if (ShellSem==NULL) { /* semaphore creation failed */ + for(;;) {} /* error, not enough memory? */ + } + vQueueAddToRegistry(ShellSem, "CLS1_Sem"); +#endif +#if CLS1_HISTORY_ENABLED + { + int i; + + CLS1_history_index = 0; + for(i=0; i0) { + io(*data++); + dataSize--; + } +} + +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void CLS1_printfPutChar(void *arg, char c) +{ + CLS1_StdIO_OutErr_FctType fct = (CLS1_StdIO_OutErr_FctType)arg; + + fct(c); /* print character */ +} + +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)io->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printf(const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)CLS1_GetStdio()->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)) +{ +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + uint8_t res; + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + int timeoutMs = CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif +#endif + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + do { + res = fct((uint8_t)ch); /* Send char, returns error code */ + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if (res==ERR_TXFULL) { + #if CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + WAIT1_WaitOSms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #else + WAIT1_Waitms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #endif + } + #endif + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS; + #endif + } while(res==ERR_TXFULL); +#else + (void)fct((uint8_t)ch); /* non blocking send */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io) +{ + #define NOF_BYTES_PER_LINE 32 /* how many bytes are shown on a line. This defines as well the chunk size we read from memory */ + #define MAX_NOF_BYTES_PER_LINE 32 + uint8_t buf[MAX_NOF_BYTES_PER_LINE]; /* this is the chunk of data we get (per line in output) */ + uint8_t str[3*MAX_NOF_BYTES_PER_LINE+((MAX_NOF_BYTES_PER_LINE+1)/8)+1]; /* maximum string for output: + - '3*' because each byte is 2 hex digits plus a space + - '(NOF_BYTES_PER_LINE+1)/8' because we add a space between every 8 byte block + - '+1' for the final zero byte */ + uint32_t addr; + uint8_t res=0, j, bufSize; + uint8_t ch; + + if (endAddrstdErr); + return ERR_RANGE; + } + for(addr=startAddr; addr<=endAddr; /* nothing */ ) { + if (endAddr-addr+1 >= bytesPerLine) { /* read only part of buffer */ + bufSize = bytesPerLine; /* read full buffer */ + } else { + bufSize = (uint8_t)(endAddr-addr+1); + } + if (readfp(hndl, addr, buf, bufSize)!=ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Read failed!\r\n", io->stdErr); + return ERR_FAILED; + } + if (res != ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Failure reading memory block!\r\n", io->stdErr); + return ERR_FAULT; + } + /* write address */ + UTIL1_strcpy(str, sizeof(str), (unsigned char*)"0x"); + UTIL1_strcatNumHex(str, sizeof(str), addr, addrSize); + UTIL1_chcat(str, sizeof(str), ':'); + CLS1_SendStr((unsigned char*)str, io->stdOut); + /* write data in hex */ + str[0] = '\0'; + for (j=0; jstdOut); + /* write in ASCII */ + io->stdOut(' '); + for (j=0; j= ' ' && ch <= 0x7f) { + io->stdOut(ch); + } else { + io->stdOut('.'); /* place holder */ + } + } + for (/*empty*/; jstdOut); + addr += bytesPerLine; + } + return ERR_OK; +} + +/* END CLS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.h new file mode 100644 index 0000000..5300446 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1.h @@ -0,0 +1,831 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:34, # CodeGen: 8 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD> " +** Project Name : tinyK22 OpenPnP +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Enabled +** Length : 32 +** Separator : ; +** Utility : UTIL1 +** Default Serial : Disabled +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + + +#ifndef __CLS1_H +#define __CLS1_H + +/* MODULE CLS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CLS1config.h" /* configuration */ + + +#ifndef __BWUserType_CLS1_StdIO_OutErr_FctType +#define __BWUserType_CLS1_StdIO_OutErr_FctType + typedef void (*CLS1_StdIO_OutErr_FctType)(uint8_t); /* Callback for an output or error I/O function */ +#endif +#ifndef __BWUserType_CLS1_StdIO_In_FctType +#define __BWUserType_CLS1_StdIO_In_FctType + typedef void (*CLS1_StdIO_In_FctType)(uint8_t *); /* Callback for an I/O input function. */ +#endif +#ifndef __BWUserType_CLS1_StdIO_KeyPressed_FctType +#define __BWUserType_CLS1_StdIO_KeyPressed_FctType + typedef bool (*CLS1_StdIO_KeyPressed_FctType)(void); /* Callback which returns true if a key has been pressed */ +#endif +#ifndef __BWUserType_CLS1_StdIOType +#define __BWUserType_CLS1_StdIOType + typedef struct { /* Record containing input, output and error callback (stdin, stdout, stderr). */ + CLS1_StdIO_In_FctType stdIn; /* standard input */ + CLS1_StdIO_OutErr_FctType stdOut; /* standard output */ + CLS1_StdIO_OutErr_FctType stdErr; /* standard error */ + CLS1_StdIO_KeyPressed_FctType keyPressed; /* key pressed callback */ + } CLS1_StdIOType; +#endif +#ifndef __BWUserType_CLS1_ConstStdIOType +#define __BWUserType_CLS1_ConstStdIOType + typedef const CLS1_StdIOType CLS1_ConstStdIOType; /* constant StdIOType */ +#endif +#ifndef __BWUserType_CLS1_ParseCommandCallback +#define __BWUserType_CLS1_ParseCommandCallback + typedef uint8_t (*CLS1_ParseCommandCallback)(const uint8_t *cmd, bool *handled, const CLS1_StdIOType *io); /* Callback for parsing a shell command */ +#endif +#ifndef __BWUserType_CLS1_ConstStdIOTypePtr +#define __BWUserType_CLS1_ConstStdIOTypePtr + typedef const CLS1_ConstStdIOType *CLS1_ConstStdIOTypePtr; /* Pointer to constant standard I/O descriptor */ +#endif +#ifndef __BWUserType_CLS1_ConstParseCommandCallback +#define __BWUserType_CLS1_ConstParseCommandCallback + typedef const CLS1_ParseCommandCallback CLS1_ConstParseCommandCallback; /* Callback for parsing a shell command */ +#endif + +#define CLS1_DEFAULT_SHELL_BUFFER_SIZE CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE /* default buffer size for shell command parsing */ + +/* Include inherited components */ + +/* other includes needed */ +#include /* for size_t */ + +/* settings for command line history */ +#define CLS1_HISTORY_ENABLED 0 /* 1: enabled, 0: disabled */ +#define CLS1_NOF_HISTORY 0 /* number of items in history */ +#define CLS1_HIST_LEN 0 /* history buffer size */ + +/* settings for silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR '#' /* with this char as first character in the cmd, printing is silent. Use a space to disable it */ +#define CLS1_NO_SILENT_PREFIX_CHAR ' ' /* used for no silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR_ENABLED (CLS1_SILENT_PREFIX_CHAR != CLS1_NO_SILENT_PREFIX_CHAR) + +/* settings for local echo */ +#define CLS1_ECHO_ENABLED 0 /* 1: enabled, 0: disabled */ + +#define CLS1_DEFAULT_SERIAL CLS1_CONFIG_DEFAULT_SERIAL /* If set to 1, then the shell implements its own StdIO which is returned by CLS1_GetStdio(); */ + +extern uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +#if CLS1_DEFAULT_SERIAL + extern CLS1_ConstStdIOType CLS1_stdio; /* default standard I/O */ +#endif + +#define CLS1_DASH_LINE "--------------------------------------------------------------" +/* predefined commands */ +#define CLS1_CMD_HELP "help" +#define CLS1_CMD_STATUS "status" + +#ifdef __cplusplus +extern "C" { +#endif + +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ + +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ + +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_Init(void); +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_RequestSerial(void); +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReleaseSerial(void); +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReadChar(uint8_t *c); +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_KeyPressed(void); +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Shell) +** +** Description : +** De-Initializes the module, especially frees the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void* CLS1_GetSemaphore(void); +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable); +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendData(const uint8_t *data, uint16_t dataSize, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendData (component Shell) +** +** Description : +** Sends data using an I/O function. Unlike SendStr(), with +** this method it is possible to send binary data, including +** zero bytes. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to be sent +** dataSize - Number of bytes to be sent. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev); +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ + +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +unsigned CLS1_printf(const char *fmt, ...); +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_printfPutChar(void *arg, char c); +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END CLS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __CLS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1config.h new file mode 100644 index 0000000..66b7dfd --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CLS1config.h @@ -0,0 +1,82 @@ +#ifndef __CLS1_CONFIG_H +#define __CLS1_CONFIG_H + +#ifndef CLS1_CONFIG_BLOCKING_SEND_ENABLED + #define CLS1_CONFIG_BLOCKING_SEND_ENABLED (1) + /*!< 1: Sending is blocking (with an optional timeout); 0: Do not block on sending */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (20) + /*!< Total blocking time (timeout) in milliseconds, uses 0 for blocking without a timeout */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS (5) + /*!< waiting time during blocking, use 0 (zero) for polling */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + #define CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT (1) + /*!< 1: Use WaitmsOS() instead of Waitms(); 0: Use Waitms() instead of WaitOSms() */ +#endif + +#ifndef CLS1_CONFIG_USE_MUTEX + #define CLS1_CONFIG_USE_MUTEX (0) + /*!< 1: use RTOS mutex; 0: do not use RTOS mutex */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE + #define CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE (48) + /*!< default buffer size for shell command parsing */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SERIAL + #define CLS1_CONFIG_DEFAULT_SERIAL (0) + /*!< 1: the shell implements its own StdIO which is returned by GetStdio(); 0: The shell does not implement its own standard I/O */ +#endif + +#if CLS1_CONFIG_DEFAULT_SERIAL + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE + #define CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE "McuSerial.h" + /*!< Include for the functions below */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME McuSerial_RecvChar + /*!< Function name to read a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME McuSerial_SendChar + /*!< Function name to send a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME McuSerial_GetCharsInRxBuf + /*!< Function name to check if there is anything available to receive and returns TRUE, otherwise FALSE */ + #endif +#endif + +#ifndef CLS1_CONFIG_PROMPT_STRING + #define CLS1_CONFIG_PROMPT_STRING "CMD> " +#endif + +#ifndef CLS1_CONFIG_PROJECT_NAME_STRING + #define CLS1_CONFIG_PROJECT_NAME_STRING "tinyK22 OpenPnP" +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_ENABLED + #define CLS1_CONFIG_MULTI_CMD_ENABLED (1) /* 1: enabled, 0: disabled */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_SIZE + #define CLS1_CONFIG_MULTI_CMD_SIZE (32) /* max size of each command */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_CHAR + #define CLS1_CONFIG_MULTI_CMD_CHAR ';' /* separation character */ +#endif + + +#endif /* __CLS1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CPU_Config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CPU_Config.h new file mode 100644 index 0000000..051a127 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CPU_Config.h @@ -0,0 +1,754 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CPU_Config.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2020-03-20, 07:56, # CodeGen: 9 +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file CPU_Config.h +** @version 01.00 +*/ +/*! +** @addtogroup CPU_Config_module CPU_Config module documentation +** @{ +*/ + +#ifndef __CPU_Config_H +#define __CPU_Config_H + +/* MODULE CPU_Config.h */ + +/* Include C integer types declaration header */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* EntryPoint function definition */ +#define PEX_ENTRYPOINT_FUNCTION __init_hardware +#define PEX_ENTRYPOINT_FUNCTION_TYPE void +#define PEX_ENTRYPOINT_FUNCTION_RETURN + +/* + Component method constants. Internal methods are not included. + + When method is enabled in the processor (CPU) component associated constant + has value 1 otherwise 0. +*/ + +#define CPU_SET_CLOCK_CONFIGURATION 0x00U +#define CPU_GET_CLOCK_CONFIGURATION 0x00U +#define CPU_SET_OPERATION_MODE 0x00U +#define CPU_ENABLE_INT 0x00U +#define CPU_DISABLE_INT 0x00U +#define CPU_MCG_AUTO_TRIM 0x00U +#define CPU_VLP_MODE_ENABLE 0x00U +#define CPU_VLP_MODE_DISABLE 0x00U +#define CPU_SYSTEM_RESET 0x00U + +/* Events constants. */ + +/* Processor (CPU) component's events are called from ISRs implemented in the Cpu.c as + code of the CPU ISRs depends on the RTOS Adaptor and may vary. Only exception is OnReset event + which is called directly as this event doesn't have any ISR. */ + + +/* + Processor type constants + + Constants specifying processor family, type or variant. +*/ + +#define CPU_FAMILY_Kinetis /* Specification of the core type of the selected processor */ +#define CPU_DERIVATIVE_MK22FN512LH12 /* Name of the selected processor derivative */ +#define CPU_PARTNUM_MK22FN512VLH12 /* Part number of the selected processor */ +#define CPU_LITTLE_ENDIAN /* The selected processor uses little endian */ + +/* + Processor clock source constants + + Constants containing frequencies of processor reference clock sources. +*/ + +#define CPU_BUS_CLK_HZ 60000000U /* Initial value of the bus clock frequency in Hz */ +#define CPU_CORE_CLK_HZ 120000000U /* Initial value of the core/system clock frequency in Hz. */ +#define CPU_XTAL_CLK_HZ 8000000U /* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768U /* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000U /* Value of the fast internal oscillator clock frequency in Hz */ +/* + Clock configuration frequency constants + + Following constants contain variety of frequency values generated by the processor + in the specific Clock configuration. + Clock configurations are used to control general processor timing + (for example core and bus clock or FLL and PLL submodules) and to predefine + up to 8 different processor timing schemes. + After reset, processor is set to the Clock configuration 0. During the + application run-time SetClockConfiguration() method can be used to switch + between predefined Clock configurations. + Clock configurations are set in the processor (CPU) component: + Clock settings\Clock configurations group of properties. +*/ + +#define CPU_CLOCK_CONFIG_NUMBER 0x01U /* Specifies number of defined clock configurations. */ + +#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0 60000000U /* Value of the bus clock frequency in the clock configuration 0 in Hz. */ +#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0 120000000U /* Value of the core/system clock frequency in the clock configuration 0 in Hz. */ + +/* CPU frequencies in clock configuration 0 */ +#define CPU_CLOCK_CONFIG_0 0x00U /* Clock configuration 0 identifier */ +#define CPU_CORE_CLK_HZ_CONFIG_0 120000000UL /* Core clock frequency in clock configuration 0 */ +#define CPU_BUS_CLK_HZ_CONFIG_0 60000000UL /* Bus clock frequency in clock configuration 0 */ +#define CPU_FLEXBUS_CLK_HZ_CONFIG_0 60000000UL /* Flexbus clock frequency in clock configuration 0 */ +#define CPU_FLASH_CLK_HZ_CONFIG_0 24000000UL /* FLASH clock frequency in clock configuration 0 */ +#define CPU_USB_CLK_HZ_CONFIG_0 0UL /* USB clock frequency in clock configuration 0 */ +#define CPU_PLL_FLL_CLK_HZ_CONFIG_0 120000000UL /* PLL/FLL clock frequency in clock configuration 0 */ +#define CPU_MCGIR_CLK_HZ_CONFIG_0 32768UL /* MCG internal reference clock frequency in clock configuration 0 */ +#define CPU_OSCER_CLK_HZ_CONFIG_0 8000000UL /* System OSC external reference clock frequency in clock configuration 0 */ +#define CPU_ERCLK32K_CLK_HZ_CONFIG_0 1000UL /* External reference clock 32k frequency in clock configuration 0 */ +#define CPU_MCGFF_CLK_HZ_CONFIG_0 31250UL /* MCG fixed frequency clock */ + + +/* Clock configuration structure declaration. Structure is initialized in PE_LDD.c */ +typedef struct { + uint32_t cpu_core_clk_hz; /* Core clock frequency in clock configuration */ + uint32_t cpu_bus_clk_hz; /* Bus clock frequency in clock configuration */ + uint32_t cpu_flexbus_clk_hz; /* Flexbus clock frequency in clock configuration */ + uint32_t cpu_flash_clk_hz; /* FLASH clock frequency in clock configuration */ + uint32_t cpu_usb_clk_hz; /* USB clock frequency in clock configuration */ + uint32_t cpu_pll_fll_clk_hz; /* PLL/FLL clock frequency in clock configuration */ + uint32_t cpu_mcgir_clk_hz; /* MCG internal reference clock frequency in clock configuration */ + uint32_t cpu_oscer_clk_hz; /* System OSC external reference clock frequency in clock configuration */ + uint32_t cpu_erclk32k_clk_hz; /* External reference clock 32k frequency in clock configuration */ + uint32_t cpu_mcgff_clk_hz; /* MCG fixed frequency clock */ +} TCpuClockConfiguration; + +/* The array of clock frequencies in configured clock configurations */ +extern const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER]; + +/* + Clock generator (MCG) mode constants + + Constants and types used to specify MCG mode and clock sources used + by the clock generator. Each mode constant consists of unique mode ID + number and mode features encoded using bit-mask. Clock sources are encoded + using just bit-mask describing source features. +*/ + +/* MCG mode and clock source features - used to fill CPU_TClockGenMode and CPU_TClockSource */ +#define CPU_CLOCK_SLOW_MASK 0x10U /* Mode uses slow internal reference clock */ +#define CPU_CLOCK_FAST_MASK 0x20U /* Mode uses fast internal reference clock */ +#define CPU_CLOCK_EXTERNAL_CLOCK_MASK 0x40U /* Mode uses external reference clock from external clock input */ +#define CPU_CLOCK_EXTERNAL_CRYSTAL_MASK 0x80U /* Mode uses external reference clock from crystal/resonator reference connection */ +#define CPU_CLOCK_RTC_OSC_MASK 0x0100U /* Mode uses RTC oscillator clock */ +#define CPU_CLOCK_PLL_MASK 0x0200U /* PLL module is enabled in other than PEE and PBE mode */ +#define CPU_CLOCK_IRC48M_MASK 0x0400U /* Mode uses internal reference clock 48MHz */ + + +/* MCG mode IDs - used to fill CPU_TClockGenMode */ +#define CPU_MCG_MODE_FEI 0x00U /* FEI mode ID */ +#define CPU_MCG_MODE_FBI 0x01U /* FBI mode ID */ +#define CPU_MCG_MODE_BLPI 0x02U /* BLPI mode ID */ +#define CPU_MCG_MODE_FEE 0x03U /* FEE mode ID */ +#define CPU_MCG_MODE_FBE 0x04U /* FBE mode ID */ +#define CPU_MCG_MODE_BLPE 0x05U /* BLPE mode ID */ +#define CPU_MCG_MODE_PBE 0x06U /* PBE mode ID */ +#define CPU_MCG_MODE_PEE 0x07U /* PEE mode ID */ +#define CPU_MCG_MODES 0x08U /* Number of available MCG modes */ +#define CPU_MCG_MODE_INDEX_MASK 0x0FU /* Mask of bits where MCG mode ID is encoded */ + +/* MCG mode type - used to specify MCG mode of each Clock configuration */ +typedef uint16_t CPU_TClockGenMode; + +/* + Very low power mode constants + + Constants used to specify very low power mode settings in each + clock configuration. +*/ + +/* Low power mode settings mask constants - used to fill CPU_TClockVeryPowerMode */ +#define CPU_CLOCK_VLP_ENABLE_MASK 0x01U /* Very low power mode enabled */ +#define CPU_CLOCK_VLP_AUTO_ENABLE_MASK 0x02U /* Very low power mode entered automatically from SetClockConfiguration method */ +#define CPU_CLOCK_VLP_WAKEUP_MASK 0x04U /* Very low power mode exited after any interrupt */ +#define CPU_CLOCK_HSRUN_ENABLE_MASK 0x08U /* High speed run mode enabled */ + +/* Low power mode settings type - used to enable/set-up Very low power mode of each Clock configuration */ +typedef uint8_t CPU_TClockPowerMode; + +/* + Clock configuration descriptor + + Following types are used to define and store settings related to + clock generator modules (i.e. MCG and OSC modules), system or common clock + dividers and selectors (SIM module) for each predefined Clock configuration. + When Clock configuration is switched the processor registers are updated + from the following descriptors. +*/ + +/* MCG and OSC module structure type + Structure with MCG and OSC configuration. To lower memory footprint the structure + doesn't contain full list of MCG and OSC registers but only those with settings + necessary to set Clock configuration. */ +typedef struct { + uint8_t MCG_C1_value; + uint8_t MCG_C2_value; + uint8_t MCG_C4_value; + uint8_t MCG_C5_value; + uint8_t MCG_C6_value; + uint8_t MCG_C7_value; + uint8_t MCG_SC_value; + uint8_t OSC_CR_value; +} CPU_TClockGenRegs; + +/* Clock system settings structure type + Structure contains system integration level clock settings - clock source + selectors and dividers which control clocks produced by MCG and OSC modules and + peripheral clock source selections common for multiple peripheral instances. */ +typedef struct { + uint32_t SIM_SOPT1_value; + uint32_t SIM_SOPT2_value; + uint32_t SIM_CLKDIV1_value; +} CPU_TClockSysRegs; + +/* Clock configuration descriptor structure type + Gathers all Clock configuration settings. Content of this structure is used + during Clock configuration set up. */ +typedef struct { + CPU_TClockGenMode Mode; + CPU_TClockPowerMode PowerMode; + CPU_TClockGenRegs GenRegs; + CPU_TClockSysRegs SysRegs; + uint32_t BusClock; +} CPU_TClockConfigDescriptor; + +/* Clock configuration structure content + + Following constants are use to initialize CPU_TClockConfigDescriptor structure + in the static CPU_Init.c module. Constants for each Clock configuration + enabled in the processor (CPU) component are generated. + + Properties: Clock settings\Clock configurations, + Clock settings\Clock source settings, + Clock settings\Clock sources. +*/ + +/* Clock configuration 0 */ +#define CPU_MCG_MODE_CONFIG_0 (CPU_MCG_MODE_PEE | CPU_CLOCK_EXTERNAL_CRYSTAL_MASK | CPU_CLOCK_SLOW_MASK) /* Clock generator mode */ +#define CPU_CLOCK_PMODE_CONFIG_0 CPU_CLOCK_HSRUN_ENABLE_MASK /* High speed RUN power mode */ + +#define CPU_MCG_C1_CONFIG_0 0x1AU /* MCG_C1 */ +#define CPU_MCG_C2_CONFIG_0 0x24U /* MCG_C2 */ +#define CPU_MCG_C4_CONFIG_0 0x00U /* MCG_C4 */ +#define CPU_MCG_C5_CONFIG_0 0x01U /* MCG_C5 */ +#define CPU_MCG_C6_CONFIG_0 0x46U /* MCG_C6 */ +#define CPU_MCG_C7_CONFIG_0 0x00U /* MCG_C7 */ +#define CPU_MCG_SC_CONFIG_0 0x00U /* MCG_SC */ +#define CPU_OSC_CR_CONFIG_0 0x80U /* OSC_CR */ +#define CPU_SIM_SOPT1_CONFIG_0 0x000C0000UL /* SIM_SOPT1 */ +#define CPU_SIM_SOPT2_CONFIG_0 0x00010000UL /* SIM_SOPT2 */ +#define CPU_SIM_CLKDIV1_CONFIG_0 0x01140000UL /* SIM_CLKDIV1 */ + +/* + Clock generator structure default content + + When Clock configurations set in the processor (CPU) component use different MCG + modes and transition between them requires passing through some intermediate MCG + mode then following constants are used to set up clock generator modules to these + intermediate MCG modes. Following constants represent CPU_TClockGenRegs structure + content loaded to the clock generator registers to configure the intermediate + mode of the generator modules. + + If setting is controlled by any property then the associated property is specified. + Rest of settings are not controlled by any property and their value is static. +*/ + + +/* Clock generator default state in FEI mode + Clock source: Slow internal reference, disabled in the STOP mode + Clock source frequency: 32.768 kHz (Property: Clock settings\Clock sources\Internal oscillator\Slow internal reference clock) + FLL: Enabled, engaged + FLL factor: 640 + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS=0,IREFS=1,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_FEI_MCG_C1 0x04U /* MCG_C1 value in FEI default state */ +/* MCG_C2: LOCRE0=1 */ +#define CPU_DEFAULT_FEI_MCG_C2 0x80U /* MCG_C2 value in FEI default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_FEI_MCG_C4 0x00U /* MCG_C4 value in FEI default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_FEI_MCG_C5 0x00U /* MCG_C5 value in FEI default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_FEI_MCG_C6 0x00U /* MCG_C6 value in FEI default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_FEI_MCG_C7 0x00U /* MCG_C7 value in FEI default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_FEI_MCG_SC 0x02U /* MCG_SC value in FEI default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_FEI_OSC_CR 0x00U /* OSC_CR value in FEI default state */ + +/* Clock generator default state in FBI mode + Clock source: Slow internal reference, disabled in the STOP mode + Clock source frequency: 32.768 kHz (Property: Clock settings\Clock sources\Internal oscillator\Slow internal reference clock) + FLL: Enabled, bypassed + FLL factor: 640 + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS|=1,IREFS=1,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_FBI_MCG_C1 0x44U /* MCG_C1 value in FBI default state */ +/* MCG_C2: LOCRE0=1 */ +#define CPU_DEFAULT_FBI_MCG_C2 0x80U /* MCG_C2 value in FBI default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_FBI_MCG_C4 0x00U /* MCG_C4 value in FBI default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_FBI_MCG_C5 0x00U /* MCG_C5 value in FBI default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_FBI_MCG_C6 0x00U /* MCG_C6 value in FBI default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_FBI_MCG_C7 0x00U /* MCG_C7 value in FBI default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_FBI_MCG_SC 0x02U /* MCG_SC value in FBI default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_FBI_OSC_CR 0x00U /* OSC_CR value in FBI default state */ + +/* Clock generator default state in BLPI mode + Clock source: Slow internal reference, disabled in the STOP mode + Clock source frequency: 32.768 kHz (Property: Clock settings\Clock sources\Internal oscillator\Slow internal reference clock) + FLL: Disabled + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS|=1,IREFS=1,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_BLPI_MCG_C1 0x44U /* MCG_C1 value in BLPI default state */ +/* MCG_C2: LOCRE0=1,LP=1 */ +#define CPU_DEFAULT_BLPI_MCG_C2 0x82U /* MCG_C2 value in BLPI default state */ +/* MCG_C4: */ +#define CPU_DEFAULT_BLPI_MCG_C4 0x00U /* MCG_C4 value in BLPI default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_BLPI_MCG_C5 0x00U /* MCG_C5 value in BLPI default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_BLPI_MCG_C6 0x00U /* MCG_C6 value in BLPI default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_BLPI_MCG_C7 0x00U /* MCG_C7 value in BLPI default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_BLPI_MCG_SC 0x02U /* MCG_SC value in BLPI default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_BLPI_OSC_CR 0x00U /* OSC_CR value in BLPI default state */ + +/* Clock generator default state in FEE mode + Clock source: External crystal (oscillator) (Property: Clock settings\Clock sources\System oscillator 0\Clock source) + Clock source frequency: 8 MHz (Property: Clock settings\Clock sources\System oscillator 0\Clock source\Clock frequency) + Operating mode: Low power + External frequency range: Very high + FLL external reference divider: 256 + FLL: Enabled, engaged + FLL factor: 640 + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS=0,FRDIV|=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_FEE_MCG_C1 0x18U /* MCG_C1 value in FEE default state */ +/* MCG_C2: LOCRE0=1,RANGE|=2,EREFS=1 */ +#define CPU_DEFAULT_FEE_MCG_C2 0xA4U /* MCG_C2 value in FEE default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_FEE_MCG_C4 0x00U /* MCG_C4 value in FEE default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_FEE_MCG_C5 0x00U /* MCG_C5 value in FEE default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_FEE_MCG_C6 0x00U /* MCG_C6 value in FEE default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_FEE_MCG_C7 0x00U /* MCG_C7 value in FEE default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_FEE_MCG_SC 0x02U /* MCG_SC value in FEE default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_FEE_OSC_CR 0x00U /* OSC_CR value in FEE default state */ + +/* Clock generator default state in FBE mode + Clock source: External crystal (oscillator) (Property: Clock settings\Clock sources\System oscillator 0\Clock source) + Clock source frequency: 8 MHz (Property: Clock settings\Clock sources\System oscillator 0\Clock source\Clock frequency) + Operating mode: Low power + External frequency range: Very high + FLL external reference divider: 256 + FLL: Enabled, bypassed + FLL factor: 640 + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS|=2,FRDIV|=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_FBE_MCG_C1 0x98U /* MCG_C1 value in FBE default state */ +/* MCG_C2: LOCRE0=1,RANGE|=2,EREFS=1 */ +#define CPU_DEFAULT_FBE_MCG_C2 0xA4U /* MCG_C2 value in FBE default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_FBE_MCG_C4 0x00U /* MCG_C4 value in FBE default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_FBE_MCG_C5 0x00U /* MCG_C5 value in FBE default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_FBE_MCG_C6 0x00U /* MCG_C6 value in FBE default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_FBE_MCG_C7 0x00U /* MCG_C7 value in FBE default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_FBE_MCG_SC 0x02U /* MCG_SC value in FBE default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_FBE_OSC_CR 0x00U /* OSC_CR value in FBE default state */ + +/* Clock generator default state in BLPE mode + Clock source: External crystal (oscillator) (Property: Clock settings\Clock sources\System oscillator 0\Clock source) + Clock source frequency: 8 MHz (Property: Clock settings\Clock sources\System oscillator 0\Clock source\Clock frequency) + Operating mode: Low power + External frequency range: Very high + FLL external reference divider: 256 + FLL: Disabled + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS|=1,FRDIV|=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_BLPE_MCG_C1 0x58U /* MCG_C1 value in BLPE default state */ +/* MCG_C2: LOCRE0=1,RANGE|=2,EREFS=1,LP=1 */ +#define CPU_DEFAULT_BLPE_MCG_C2 0xA6U /* MCG_C2 value in BLPE default state */ +/* MCG_C4: */ +#define CPU_DEFAULT_BLPE_MCG_C4 0x00U /* MCG_C4 value in BLPE default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=0 */ +#define CPU_DEFAULT_BLPE_MCG_C5 0x00U /* MCG_C5 value in BLPE default state */ +/* MCG_C6: LOLIE0=0,CME0=0,VDIV0=0 */ +#define CPU_DEFAULT_BLPE_MCG_C6 0x00U /* MCG_C6 value in BLPE default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_BLPE_MCG_C7 0x00U /* MCG_C7 value in BLPE default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_BLPE_MCG_SC 0x02U /* MCG_SC value in BLPE default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_BLPE_OSC_CR 0x00U /* OSC_CR value in BLPE default state */ +/* Clock generator default state in PEE mode + Clock source: External crystal (oscillator) (Property: Clock settings\Clock sources\System oscillator 0\Clock source) + Clock source frequency: 8 MHz (Property: Clock settings\Clock sources\System oscillator 0\Clock source\Clock frequency) + Operating mode: Low power + PLL External Reference Divider %EXPE(1 + 1) + PLL Multiplier 48 + PLL: Enabled, engaged + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS=0,FRDIV|=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_PEE_MCG_C1 0x18U /* MCG_C1 value in PEE default state */ +/* MCG_C2: LOCRE0=1,RANGE|=2,EREFS=1 */ +#define CPU_DEFAULT_PEE_MCG_C2 0xA4U /* MCG_C2 value in PEE default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_PEE_MCG_C4 0x00U /* MCG_C4 value in PEE default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0|=1 */ +#define CPU_DEFAULT_PEE_MCG_C5 0x01U /* MCG_C5 value in PEE default state */ +/* MCG_C6: PLLS=1,CME0=0,VDIV0|=0x18 */ +#define CPU_DEFAULT_PEE_MCG_C6 0x58U /* MCG_C6 value in PEE default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_PEE_MCG_C7 0x00U /* MCG_C7 value in PEE default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_PEE_MCG_SC 0x02U /* MCG_SC value in PEE default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_PEE_OSC_CR 0x00U /* OSC_CR value in PEE default state */ +/* Clock generator default state in PBE mode + Clock source: External crystal (oscillator) (Property: Clock settings\Clock sources\System oscillator 0\Clock source) + Clock source frequency: 8 MHz (Property: Clock settings\Clock sources\System oscillator 0\Clock source\Clock frequency) + Operating mode: Low power + PLL External Reference Divider %EXPE(1 + 1) + PLL Multiplier 48 + PLL: Enabled, bypassed + Internal reference clock (MCGIRCLK): Disabled + External reference clock (OSCERCLK): Disabled + External clock monitor: Disabled + Loss of clock reset: Enabled +*/ +/* MCG_C1: CLKS|=2,IREFS=0,IRCLKEN=0,IREFSTEN=0 */ +#define CPU_DEFAULT_PBE_MCG_C1 0x80U /* MCG_C1 value in PBE default state */ +/* MCG_C2: LOCRE0=1,RANGE|=2,EREFS=1 */ +#define CPU_DEFAULT_PBE_MCG_C2 0xA4U /* MCG_C2 value in PBE default state */ +/* MCG_C4: DMX32=0,DRST_DRS=0 */ +#define CPU_DEFAULT_PBE_MCG_C4 0x00U /* MCG_C4 value in PBE default state */ +/* MCG_C5: PLLCLKEN0=0,PLLSTEN0=0,PRDIV0|=1 */ +#define CPU_DEFAULT_PBE_MCG_C5 0x01U /* MCG_C5 value in PBE default state */ +/* MCG_C6: PLLS=1,CME0=0,VDIV0|=0x18 */ +#define CPU_DEFAULT_PBE_MCG_C6 0x58U /* MCG_C6 value in PBE default state */ +/* MCG_C7: OSCSEL=0 */ +#define CPU_DEFAULT_PBE_MCG_C7 0x00U /* MCG_C7 value in PBE default state */ +/* MCG_SC: FCRDIV|=1 */ +#define CPU_DEFAULT_PBE_MCG_SC 0x02U /* MCG_SC value in PBE default state */ +/* OSC_CR: ERCLKEN=0,EREFSTEN=0 */ +#define CPU_DEFAULT_PBE_OSC_CR 0x00U /* OSC_CR value in PBE default state */ + +/* + Low power mode settings + + Following constants are used for SetOperationMode() method parameterization. + This method switches 4 driver operation modes - RUN, WAIT, SLEEP and STOP. + These driver operation modes represents higher-level abstraction and maps + hardware power modes as follows: + + Driver mode Hardware mode + RUN : RUN / (VLPR)* + WAIT : WAIT / (VLPW)* + SLEEP : Normal STOP / (VLPS)* + STOP : VLLS0 / VLLS2 / VLLS1 / VLLS3 / LLS + + Very-low-power modes marked with ()* can be entered after additional + VLPModeEnable() method call. + Specific SLEEP or STOP mode entered after SetOperationMode() call is selected + in the processor (CPU) component. + + Properties: Low power mode settings\Operation mode settings\WAIT operation mode + Low power mode settings\Operation mode settings\SLEEP operation mode + Low power mode settings\Operation mode settings\STOP operation mode +*/ + +/* WAIT operation mode settings */ +#define CPU_LOW_POWER_WAIT_SLEEP_ON_EXIT 0x00U /* ARM sleep-on-exit is disabled in WAIT operation mode (when the lowest priority ISR is exited then processor state unstacking is done before system goes back to low-power mode) */ + +/* SLEEP operation mode settings */ +#define CPU_LOW_POWER_SLEEP_MODE 0x00U /* Normal STOP entered in the SLEEP operation mode */ +#define CPU_LOW_POWER_SLEEP_SLEEP_ON_EXIT 0x00U /* ARM sleep-on-exit is disabled in STOP operation mode (when the lowest priority ISR is exited unstacking is done before system goes back to low-power mode) */ + +/* STOP operation mode settings */ +#define CPU_LOW_POWER_STOP_VLLS0 0x01U /* Very-Low-Leakage Stop 0 */ +#define CPU_LOW_POWER_STOP_VLLS1 0x02U /* Very-Low-Leakage Stop 1 */ +#define CPU_LOW_POWER_STOP_VLLS3 0x03U /* Very-Low-Leakage Stop 3 */ +#define CPU_LOW_POWER_STOP_VLLS2 0x04U /* Very-Low-Leakage Stop 2 */ +#define CPU_LOW_POWER_STOP_LLS 0x05U /* Low-Leakage Stop */ + +/* After reset values optimization */ + +/* Property: Common settings\Utilize after reset values */ +#define CPU_AFTER_RESET_VALUES 0x00U /* After reset values optimization is disabled */ + +/* + Startup - parameterization + + Following constants contains parameterization of the MCU startup sequence + placed in the __init_hardware() method according to Processor Expert + CPU component settings but can be used to parameterize any user startup + code. + Values of the constants are generated from the component properties + specified in comments. If not specified differently, value 0 = feature + disabled and 1 = feature enabled. If constant has no defined value it + means feature is not used. +*/ + +/* Watchdog initialization */ + +/* Property: Common settings\Watchdog disable */ +#define STARTUP_WDOG 0x01U /* Watchdog disabled */ +#define STARTUP_WDOG_KEY_1 0xC520U /* Watchdog unlock key 1 */ +#define STARTUP_WDOG_KEY_2 0xD928U /* Watchdog unlock key 2 */ + +/* System clock initialization */ +#define STARTUP_RTCOSC 0x00U /* RTC oscillator not initialized */ + +/* Internal reference clock trim initialization + Properties: Clock settings\Clock sources\Internal oscillator\Initialize slow trim value */ +#undef STARTUP_CLOCK_INTERNAL_SLOW_TRIM_ADDRESS /* Slow oscillator not trimmed */ +#undef STARTUP_CLOCK_INTERNAL_SLOW_FINE_TRIM_ADDRESS /* Slow oscillator not trimmed */ +/* Properties: Clock settings\Clock sources\Internal oscillator\Initialize fast trim value */ +#undef STARTUP_CLOCK_INTERNAL_FAST_TRIM_ADDRESS /* Fast oscillator not trimmed */ +#undef STARTUP_CLOCK_INTERNAL_FAST_FINE_TRIM_ADDRESS /* Fast oscillator not trimmed */ + +/* + Startup - register values + + Following constants represents the full set of registers accessed during + MCU startup sequence placed in the __init_hardware() method and their values + depends on Processor Expert's processor (CPU) component settings. + The constants have values of registers after the startup is finished. + Although the list of registers accessed during the startup sequence may vary + across different CPU component settings, following constants represents + a superset of all registers which might be accessed. If register or register + bitfield is not modified during the particular startup sequence + then its after reset value is presented. + If register or register bitfield is accessed multiple times during the startup + then the last written value is used. +*/ + +/* WDOG */ + +#define STARTUP_WDOG_STCTRLH_VALUE 0x01D2U /* WDOG_STCTRLH value */ + +/* MCG */ + +#define STARTUP_MCG_C1_VALUE 0x1AU /* MCG_C1 value */ +#define STARTUP_MCG_C2_VALUE 0x24U /* MCG_C2 value */ +#define STARTUP_MCG_C3_VALUE 0x00U /* MCG_C3 value */ +#define STARTUP_MCG_C4_VALUE 0x00U /* MCG_C4 value */ +#define STARTUP_MCG_C6_VALUE 0x00U /* MCG_C6 value */ +#define STARTUP_MCG_SC_VALUE 0x02U /* MCG_SC value */ + +/* OSC0 */ + +#define STARTUP_OSC_CR_VALUE 0x80U /* OSC_CR value */ + +/* SIM */ + +#define STARTUP_SIM_SOPT1_VALUE 0x000C0000UL /* SIM_SOPT1 value */ +#define STARTUP_SIM_SOPT2_VALUE 0x00010000UL /* SIM_SOPT2 value */ +#define STARTUP_SIM_CLKDIV1_VALUE 0x01140000UL /* SIM_CLKDIV1 value */ +#define STARTUP_SIM_SCGC5_VALUE 0x00040382UL /* SIM_SCGC5 value */ + +/* + PE_low_level_init() parameterization constants + + Following constants contains parameterization of the PE_low_level_init() + method called at the main() method. + Values of the constants are generated from the component properties + specified in comments. If not specified differently, value 0 = feature + disabled and 1 = feature enabled. If constant has no defined value it + means feature is not used. +*/ + +/* Non-maskable interrupt pin initialization + Property: Common settings\NMI pin */ +#define CPU_NMI_PIN 0x01U /* NMI pin initialized */ + +/* JTAG TDI pin initialization + Property: Common settings\Debug interface (JTAG)\TDI pin */ +#define CPU_JTAG_TDI_PIN 0x01U /* JTAG TDI pin initialized */ + +/* JTAG TDO pin initialization + Property: Common settings\Debug interface (JTAG)\TDO pin */ +#define CPU_JTAG_TDO_PIN 0x01U /* JTAG TDO pin initialized */ + +/* JTAG TCK pin initialization + Property: Common settings\Debug interface (JTAG)\TCK pin */ +#define CPU_JTAG_TCK_PIN 0x01U /* JTAG TCK pin initialized */ + +/* JTAG TMS pin initialization + Property: Common settings\Debug interface (JTAG)\TMS pin */ +#define CPU_JTAG_TMS_PIN 0x01U /* JTAG TMS pin initialized */ + +/* JTAG TRST pin initialization + Property: Common settings\Debug interface (JTAG)\nTRST pin */ +#define CPU_JTAG_TRST_PIN 0x00U /* JTAG nTRST pin not initialized */ + +/* Low power modes protection initialization + Properties: Low power mode settings\Allowed low power modes */ +#define CPU_LOW_POWER_ALLOW_VLP 0x00U /* VLPR VLPW and VLPS are not allowed */ +#define CPU_LOW_POWER_ALLOW_LLS 0x00U /* LLS isn't allowed */ +#define CPU_LOW_POWER_ALLOW_VLLS 0x00U /* No VLLSx mode is allowed */ +#define CPU_LOW_POWER_ALLOW_HSRUN 0x01U /* HSRUN mode is allowed */ + +/* Flash configuration field constants */ +#define CPU_FLASH_CONFIG_FIELD \ + /* NV_BACKKEY3: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY2: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY1: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY0: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY7: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY6: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY5: KEY=0xFF */ \ + 0xFFU, \ + /* NV_BACKKEY4: KEY=0xFF */ \ + 0xFFU, \ + /* NV_FPROT3: PROT=0xFF */ \ + 0xFFU, \ + /* NV_FPROT2: PROT=0xFF */ \ + 0xFFU, \ + /* NV_FPROT1: PROT=0xFF */ \ + 0xFFU, \ + /* NV_FPROT0: PROT=0xFF */ \ + 0xFFU, \ + /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */ \ + 0x7EU, \ + /* NV_FOPT: ??=1,??=1,FAST_INIT=1,??=1,??=1,NMI_DIS=1,EZPORT_DIS=1,LPBOOT=1 */ \ + 0xFFU, \ + /* Reserved */ \ + 0xFFU, \ + /* Reserved */ \ + 0xFFU + +/* Common_Init() parameterization settings */ + +#define CPU_COMMON_INIT 0x01U /* Call Common_Init() method in PE_low_level_init() */ + +/* Peripherals_Init() parameterization settings */ + +#define CPU_PERIPHERALS_INIT 0x01U /* Call Peripherals_Init() method in PE_low_level_init() */ + +/* Components_Init() parameterization settings */ + +#define CPU_COMPONENTS_INIT 0x01U /* Call Components_Init() method in PE_low_level_init() */ + +/* Interrupts priority level settings */ + +/* Property: Common settings\Initialization priority */ +#define CPU_INT_PRIORITY 0xF0U /* Priority level constant of enabled interrupts initialized in PE_low_level_init() */ + +#ifdef __cplusplus +} +#endif + +#endif +/* __CPU_Config_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.c new file mode 100644 index 0000000..d19a607 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.c @@ -0,0 +1,151 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +/* MODULE CS1. */ + +#include "CS1.h" + +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_CriticalVariable(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_EnterCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_ExitCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Init(void) +{ + /* nothing needed */ +} + +/* END CS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.h new file mode 100644 index 0000000..b8daeb9 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1.h @@ -0,0 +1,216 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +#ifndef __CS1_H +#define __CS1_H + +/* MODULE CS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CS1config.h" /* configuration */ + + +/* other includes needed */ +#if CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #include "FreeRTOS.h" + #include "task.h" /* FreeRTOS header file for taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* workaround macros for wrong EnterCritical()/ExitCritical() in the low level drivers. */ +#define CS1_CriticalVariableDrv() \ + CS1_CriticalVariable() +#define CS1_EnterCriticalDrv() \ + CS1_EnterCritical() +#define CS1_ExitCriticalDrv() \ + CS1_ExitCritical() + +#ifdef __HIWARE__ + #pragma MESSAGE DISABLE C3303 /* C3303 Implicit concatenation of strings */ +#endif + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_CriticalVariable() /* nothing needed */ + #else + #define CS1_CriticalVariable() uint8_t cpuSR; /* variable to store current status */ + #endif +#endif +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_EnterCritical() EnterCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_EnterCritical() taskENTER_CRITICAL_FROM_ISR() /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_EnterCritical() \ + do { \ + __asm volatile( "csrc mstatus, 8" ); /* Disable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_EnterCritical() \ + do { \ + /*lint -save -esym(529,cpuSR) Symbol 'cpuSR' not subsequently referenced. */\ + __asm ( \ + "mrs r0, PRIMASK \n\t" \ + "cpsid i \n\t" \ + "strb r0, %[output] \n\t" \ + : [output] "=m" (cpuSR) :: "r0"); \ + __asm ("" ::: "memory"); \ + /*lint -restore Symbol 'cpuSR' not subsequently referenced. */\ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_ExitCritical() ExitCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_ExitCritical() taskEXIT_CRITICAL_FROM_ISR(0) /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_ExitCritical() \ + do { \ + __asm volatile( "csrs mstatus, 8" ); /* Enable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_ExitCritical() \ + do{ \ + __asm ( \ + "ldrb r0, %[input] \n\t" \ + "msr PRIMASK,r0 \n\t" \ + ::[input] "m" (cpuSR) : "r0"); \ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Init(void); +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END CS1. */ + +#ifdef __cplusplus +} +#endif + +#endif +/* ifndef __CS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1config.h new file mode 100644 index 0000000..2fe3b70 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/CS1config.h @@ -0,0 +1,18 @@ +#ifndef __CS1_CONFIG_H +#define __CS1_CONFIG_H + +/* select ONE of the following implementation methods: */ +#ifndef CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CONFIG_USE_RTOS_CRITICAL_SECTION 0 /* 1: use FreeRTOS critical section; 0: don't use FreeRTOS critical sections */ +#endif + +#ifndef CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #define CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION 1 /* 1: Custom implementation (supported for GNU and ARM!); 0: don't use custom implementation */ +#endif + +#ifndef CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CONFIG_USE_PEX_DEFAULT 0 /* 1: use Processor Expert default; 0: use alternative implementation */ +#endif + +#endif /* __CS1_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.c new file mode 100644 index 0000000..70b9bd0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.c @@ -0,0 +1,190 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : MK22FN512LH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K22P121M120SF7RM, Rev. 1, March 24, 2014 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:53, # CodeGen: 5 +** Abstract : +** +** Settings : +** +** Contents : +** No public methods +** +** (c) Freescale Semiconductor, Inc. +** 2004 All Rights Reserved +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.c +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +/* MODULE Cpu. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "Cpu.h" +#include "Events.h" +#include "Init_Config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : Common_Init (component MK22FN512LH12) +** Description : +** Initialization of registers for that there is no +** initialization component. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if CPU_COMMON_INIT +void Common_Init(void) +{ + /* Common initialization of registers which initialization is required + for proper functionality of components in the project but initialization + component which would be configuring these registers is missing + in the project. + Add associated initialization component to the project to avoid + initialization of registers in the Common_Init(). + Also, after reset value optimization property affects initialization of + registers in this method (see active generator configuration + Optimizations\Utilize after reset values property or enabled processor + component Common settings\Utilize after reset values property) */ + /* SIM_CLKDIV2: USBDIV=4,USBFRAC=1 */ + SIM_CLKDIV2 = (uint32_t)((SIM_CLKDIV2 & (uint32_t)~(uint32_t)( + SIM_CLKDIV2_USBDIV(0x03) + )) | (uint32_t)( + SIM_CLKDIV2_USBDIV(0x04) | + SIM_CLKDIV2_USBFRAC_MASK + )); + /* SIM_SCGC4: USBOTG=1 */ + SIM_SCGC4 |= SIM_SCGC4_USBOTG_MASK; + /* SIM_SOPT2: USBSRC=1 */ + SIM_SOPT2 |= SIM_SOPT2_USBSRC_MASK; + /* NVICIP53: PRI53=0 */ + NVICIP53 = NVIC_IP_PRI53(0x00); +} + +#endif /* CPU_COMMON_INIT */ + +/* +** =================================================================== +** Method : Components_Init (component MK22FN512LH12) +** Description : +** Initialization of components (with exception for Peripheral +** Initialization Components which are initialized in +** Peripherals_Init() method). +** For example, if automatic initialization feature +** is enabled in LDD component then its Init method call +** is executed in Components_Init() method. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if CPU_COMPONENTS_INIT +void Components_Init(void) +{ + MCUC1_Init(); /* ### McuLibConfig "MCUC1" init code ... */ + UTIL1_Init(); /* ### Utility "UTIL1" init code ... */ + KIN1_Init(); /* ### KinetisTools "KIN1" init code ... */ + WAIT1_Init(); /* ### Wait "WAIT1" init code ... */ + XF1_Init(); /* ### XFormat "XF1" init code ... */ + CS1_Init(); /* ### CriticalSection "CS1" init code ... */ + CLS1_Init(); /* ### Shell "CLS1" init code ... */ + /* PEX_RTOS_INIT() is a macro should already have been called either from main() + or Processor Expert startup code. So we don't call it here again. */ + /* PEX_RTOS_INIT(); */ /* ### FreeRTOS "FRTOS1" init code ... */ + /* ### BitIO_LDD "BitIoLdd1" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd1_Init(NULL); + LED1_Init(); /* ### LED "LED1" init code ... */ + RTT1_Init(); /* ### SeggerRTT "RTT1" init code ... */ + /* ### PercepioTrace "PTRC1" init code ... */ + /* ### Asynchro serial "AS1" init code ... */ + AS1_Init(); + /* ### Timeout "TMOUT1" init code ... */ + TMOUT1_Init(); + Tx1_Init(); /* ### RingBuffer "Tx1" init code ... */ + Rx1_Init(); /* ### RingBuffer "Rx1" init code ... */ + (void)USB1_Init(); + /* ### Asynchro serial "AS2" init code ... */ + AS2_Init(); +} +#endif /* CPU_COMPONENTS_INIT */ + +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK22FN512LH12) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_INT_NMIInterrupt) +{ + Cpu_OnNMI(); +} + + +#ifdef __cplusplus +} +#endif + +/* END Cpu. */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.h new file mode 100644 index 0000000..5fb5d9d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Cpu.h @@ -0,0 +1,151 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : MK22FN512LH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K22P121M120SF7RM, Rev. 1, March 24, 2014 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** +** Settings : +** +** Contents : +** No public methods +** +** (c) Freescale Semiconductor, Inc. +** 2004 All Rights Reserved +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +#ifndef __Cpu_H +#define __Cpu_H + +/* MODULE Cpu. */ + +/*Include shared modules, which are used for whole project*/ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +#include "assert.h" +#include "CPU_Init.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Active configuration define symbol */ +#define PEcfg_FLASH 1U + +/* +** =================================================================== +** Method : Common_Init (component MK22FN512LH12) +** Description : +** Initialization of registers for that there is no +** initialization component. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if CPU_COMMON_INIT +void Common_Init(void); +#endif /* CPU_COMMON_INIT */ + +/* +** =================================================================== +** Method : Components_Init (component MK22FN512LH12) +** Description : +** Initialization of components (with exception for Peripheral +** Initialization Components which are initialized in +** Peripherals_Init() method). +** For example, if automatic initialization feature +** is enabled in LDD component then its Init method call +** is executed in Components_Init() method. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if CPU_COMPONENTS_INIT +void Components_Init(void); +#endif /* CPU_COMPONENTS_INIT */ + +/* Method synonyms. Following constants maps static CPU methods with enabled user methods of which names are derived from the CPU component name */ + + +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK22FN512LH12) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(Cpu_INT_NMIInterrupt); + + +#ifdef __cplusplus +} +#endif + +/* END Cpu. */ + +#endif +/* __Cpu_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.c new file mode 100644 index 0000000..e6de41c --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.c @@ -0,0 +1,5090 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:34, # CodeGen: 8 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Enabled +** Use Tick Counter : no +** LDD : Enabled +** Runtime Counter LDD : RuntimeCntrLDD +** non-LDD : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4F +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 200 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 1000 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 8192 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 4: merge free blocks +** Static Allocation : Disabled +** User Memory Section : Disabled +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Enabled +** Max number of tasks : 16 +** Shell : CLS1 +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** vTaskGetRunTimeStats - void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** ParseCommand - uint8_t FRTOS1_ParseCommand(const unsigned char *cmd, bool *handled, const... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + +/* MODULE FRTOS1. */ +#include "FRTOS1.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portTicks.h" /* interface to tick counter */ +#include "RTOSCNTRLDD1.h" /* Interface to LDD Counter Interrupt */ + +#include "UTIL1.h" +#if configHEAP_SCHEME_IDENTIFICATION + /* special variable identifying the used heap scheme */ + const uint8_t freeRTOSMemoryScheme = configUSE_HEAP_SCHEME; +#endif + +uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ +LDD_TDeviceData *FRTOS1_RunTimeCounterHandle; /* runtime counter handle, used for configGENERATE_RUNTIME_STATS */ + +#if configUSE_SHELL +static uint8_t PrintTaskList(const CLS1_StdIOType *io) { + #define SHELL_MAX_NOF_TASKS 16 /* maximum number of tasks, as specified in the properties */ + UBaseType_t nofTasks, i; + TaskHandle_t taskHandles[SHELL_MAX_NOF_TASKS]; +#if configUSE_TRACE_FACILITY + TaskStatus_t taskStatus; +#endif + StackType_t *stackBeg, *stackEnd, *topOfStack; + uint8_t staticallyAllocated; + uint8_t buf[32], tmpBuf[32], res; + uint16_t stackSize; +#if configGENERATE_RUN_TIME_STATS + uint32_t ulTotalTime, ulStatsAsPercentage; +#endif +#if configUSE_TRACE_FACILITY + #define PAD_STAT_TASK_TCB (sizeof("TCB ")-1) +#endif + #define PAD_STAT_TASK_STATIC (sizeof("yes(2) ")-1) + #define PAD_STAT_TASK_HANDLE (sizeof("0x20000398 ")-1) + #define PAD_STAT_TASK_NAME (configMAX_TASK_NAME_LEN+1) +#if configUSE_TRACE_FACILITY + #define PAD_STAT_TASK_STATE (sizeof("Suspended")-1) +#endif +#if configUSE_TRACE_FACILITY + #define PAD_STAT_TASK_PRIO (sizeof("(10,12) ")-1) +#else + #define PAD_STAT_TASK_PRIO (sizeof("Prio ")-1) +#endif + #define PAD_STAT_TASK_STACK_BEG (sizeof("0x20000398 ")-1) + #define PAD_STAT_TASK_STACK_END (sizeof("0x20000398 ")-1) + #define PAD_STAT_TASK_STACK_SIZE (sizeof("12000 B ")-1) + #define PAD_STAT_TASK_STACK_TOP (sizeof("0x200006FC ( 132 B) ")-1) +#if configUSE_TRACE_FACILITY + #define PAD_STAT_TASK_STACK_MARK (sizeof("12345 B ")-1) +#endif +#if configGENERATE_RUN_TIME_STATS + #define PAD_STAT_TASK_RUNTIME (sizeof("0x20000398 (100%)")-1) +#endif + + res = ERR_OK; +#if !configUSE_TRACE_FACILITY + CLS1_SendStr((uint8_t*)"Info: Enable configUSE_TRACE_FACILITY for additional task information.\r\n", io->stdOut); +#endif +#if !configGENERATE_RUN_TIME_STATS + CLS1_SendStr((uint8_t*)"Info: Enable configGENERATE_RUN_TIME_STATS for runtime statistics.\r\n", io->stdOut); +#endif + /* header */ +#if configUSE_TRACE_FACILITY + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"TCB", ' ', PAD_STAT_TASK_TCB); + CLS1_SendStr(buf, io->stdOut); +#endif + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Static", ' ', PAD_STAT_TASK_STATIC); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Handle", ' ', PAD_STAT_TASK_HANDLE); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Name", ' ', PAD_STAT_TASK_NAME); + CLS1_SendStr(buf, io->stdOut); + +#if configUSE_TRACE_FACILITY + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"State", ' ', PAD_STAT_TASK_STATE); + CLS1_SendStr(buf, io->stdOut); +#endif + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Prio", ' ', PAD_STAT_TASK_PRIO); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Stack Beg", ' ', PAD_STAT_TASK_STACK_BEG); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Stack End", ' ', PAD_STAT_TASK_STACK_END); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Size", ' ', PAD_STAT_TASK_STACK_SIZE); + CLS1_SendStr(buf, io->stdOut); + + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Stack Top", ' ', PAD_STAT_TASK_STACK_TOP); + CLS1_SendStr(buf, io->stdOut); +#if configUSE_TRACE_FACILITY + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Unused", ' ', PAD_STAT_TASK_STACK_MARK); + CLS1_SendStr(buf, io->stdOut); +#endif +#if configGENERATE_RUN_TIME_STATS + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (const unsigned char*)"Runtime", ' ', PAD_STAT_TASK_RUNTIME); + CLS1_SendStr(buf, io->stdOut); +#endif + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + +#if configGENERATE_RUN_TIME_STATS + ulTotalTime = portGET_RUN_TIME_COUNTER_VALUE(); /* get total time passed in system */ + ulTotalTime /= 100UL; /* For percentage calculations. */ +#endif + + nofTasks = uxTaskGetNumberOfTasks(); + if (nofTasks>SHELL_MAX_NOF_TASKS) { + UTIL1_strcpy(buf, sizeof(buf), (const unsigned char*)"WARNING: more tasks than Shell maximum number of tasks.\r\n"); + CLS1_SendStr(buf, io->stdErr); + nofTasks = SHELL_MAX_NOF_TASKS; + } + /* get task handles of all tasks. */ + nofTasks = xGetTaskHandles(&taskHandles[0], SHELL_MAX_NOF_TASKS); + for(i=0;istdOut); +#endif + /* Static */ + tmpBuf[0] = '\0'; + if (staticallyAllocated==0) { + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"no (0)"); + } else { + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"yes("); + UTIL1_strcatNum8u(tmpBuf, sizeof(tmpBuf), staticallyAllocated); + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)")"); + } + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STATIC); + CLS1_SendStr(buf, io->stdOut); + + /* task handle */ + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x"); + UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), (uint32_t)taskHandles[i]); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_HANDLE); + CLS1_SendStr(buf, io->stdOut); + + /* task name */ + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), (unsigned char*)pcTaskGetName(taskHandles[i]), ' ', PAD_STAT_TASK_NAME); + CLS1_SendStr(buf, io->stdOut); + +#if configUSE_TRACE_FACILITY + /* state */ + switch(taskStatus.eCurrentState) { + case eRunning: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Running"); break; + case eReady: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Ready"); break; + case eSuspended: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Suspended"); break; + case eBlocked: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Blocked"); break; + case eDeleted: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Deleted"); break; + case eInvalid: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"Invalid"); break; + default: UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"UNKNOWN!"); break; + } + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STATE); + CLS1_SendStr(buf, io->stdOut); +#endif +#if configUSE_TRACE_FACILITY + /* (baseprio,currprio) */ + tmpBuf[0] = '\0'; + UTIL1_chcat(tmpBuf, sizeof(tmpBuf), '('); + UTIL1_strcatNum32u(tmpBuf, sizeof(tmpBuf), taskStatus.uxBasePriority); + UTIL1_chcat(tmpBuf, sizeof(tmpBuf), ','); + UTIL1_strcatNum32u(tmpBuf, sizeof(tmpBuf), taskStatus.uxCurrentPriority); + UTIL1_chcat(tmpBuf, sizeof(tmpBuf), ')'); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_PRIO); + CLS1_SendStr(buf, io->stdOut); +#else + /* prio */ + tmpBuf[0] = '\0'; + UTIL1_strcatNum32s(tmpBuf, sizeof(tmpBuf), uxTaskPriorityGet(taskHandles[i])); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_PRIO); + CLS1_SendStr(buf, io->stdOut); +#endif + /* stack begin */ + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x"); + UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), (uint32_t)stackBeg); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STACK_BEG); + CLS1_SendStr(buf, io->stdOut); + + /* stack end */ + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x"); + UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), (uint32_t)stackEnd); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STACK_END); + CLS1_SendStr(buf, io->stdOut); + + /* stack size */ +#if (portSTACK_GROWTH>0) + stackSize = (uint16_t)(((uint32_t)stackEnd - (uint32_t)stackBeg)+sizeof(StackType_t)); +#else + stackSize = (uint16_t)(((uint32_t)stackBeg - (uint32_t)stackEnd)+ 2*sizeof(StackType_t)); +#endif + tmpBuf[0] = '\0'; + UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), stackSize, ' ', 5); + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" B"); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STACK_SIZE); + CLS1_SendStr(buf, io->stdOut); + + /* stack top */ + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x"); + UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), (uint32_t)topOfStack); + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" ("); +#if (portSTACK_GROWTH>0) + UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), (uint16_t)(((uint32_t)topOfStack - (uint32_t)stackBeg))+sizeof(StackType_t), ' ', 5); +#else + UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), (uint16_t)(((uint32_t)stackBeg - (uint32_t)topOfStack))+sizeof(StackType_t), ' ', 5); +#endif + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" B)"); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STACK_TOP); + CLS1_SendStr(buf, io->stdOut); + +#if configUSE_TRACE_FACILITY + /* stack high water mark (the lower the number, the less stack available */ + tmpBuf[0] = '\0'; + UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), taskStatus.usStackHighWaterMark*sizeof(portSTACK_TYPE), ' ', 5); + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" B"); + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_STACK_MARK); + CLS1_SendStr(buf, io->stdOut); +#endif +#if configGENERATE_RUN_TIME_STATS && configUSE_TRACE_FACILITY + /* runtime */ + UTIL1_strcpy(tmpBuf, sizeof(tmpBuf), (unsigned char*)"0x"); + UTIL1_strcatNum32Hex(tmpBuf, sizeof(tmpBuf), taskStatus.ulRunTimeCounter); + if (ulTotalTime>0) { /* to avoid division by zero */ + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTime has already been divided by 100. */ + ulStatsAsPercentage = taskStatus.ulRunTimeCounter/ulTotalTime; + if (ulStatsAsPercentage>0) { + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" ("); + UTIL1_strcatNum16uFormatted(tmpBuf, sizeof(tmpBuf), ulStatsAsPercentage, ' ', 3); + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)"%)"); + } else { + /* If the percentage is zero here then the task has consumed less than 1% of the total run time. */ + UTIL1_strcat(tmpBuf, sizeof(tmpBuf), (unsigned char*)" ( <1%)"); + } + } + buf[0] = '\0'; + UTIL1_strcatPad(buf, sizeof(buf), tmpBuf, ' ', PAD_STAT_TASK_RUNTIME); + CLS1_SendStr(buf, io->stdOut); +#endif + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + } /* for */ + } /* if */ + return res; +} +#endif + +#if configUSE_SHELL +static uint8_t PrintStatus(const CLS1_StdIOType *io) { + uint8_t buf[16]; + + CLS1_SendStatusStr((unsigned char*)"FRTOS1", (unsigned char*)"\r\n", io->stdOut); + CLS1_SendStatusStr((unsigned char*)" Version", (const unsigned char*)tskKERNEL_VERSION_NUMBER, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStatusStr((unsigned char*)" RTOS ticks", (const unsigned char*)"", io->stdOut); + UTIL1_Num16sToStr(buf, sizeof(buf), configTICK_RATE_HZ); + CLS1_SendStr(buf, io->stdOut); + CLS1_SendStr((unsigned char*)" Hz, ", io->stdOut); + UTIL1_Num16sToStr(buf, sizeof(buf), 1000/configTICK_RATE_HZ); + CLS1_SendStr(buf, io->stdOut); + CLS1_SendStr((unsigned char*)" ms\r\n", io->stdOut); +#if configSUPPORT_DYNAMIC_ALLOCATION && configUSE_HEAP_SCHEME!=3 /* wrapper to malloc() does not have xPortGetFreeHeapSize() */ + CLS1_SendStatusStr((unsigned char*)" Free heap", (const unsigned char*)"", io->stdOut); + UTIL1_Num32uToStr(buf, sizeof(buf), FRTOS1_xPortGetFreeHeapSize()); + CLS1_SendStr(buf, io->stdOut); + CLS1_SendStr((unsigned char*)" bytes\r\n", io->stdOut); +#endif + return ERR_OK; +} +#endif + +#if configUSE_SHELL +static uint8_t PrintHelp(const CLS1_StdIOType *io) { + CLS1_SendHelpStr((unsigned char*)"FRTOS1", (unsigned char*)"Group of FRTOS1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" tasklist", (unsigned char*)"Print tasklist\r\n", io->stdOut); + return ERR_OK; +} +#endif + +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskStartScheduler(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskYIELD(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENTER_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskEXIT_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskDISABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspendAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelay(portTickType xTicksToDelay) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType xTimeIncrement) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE uxNewPriority) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ +/* +pVoid FRTOS1_pvPortMalloc(size_t xWantedSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vPortFree(void *pv) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCount(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskGetRunTimeStats (component FreeRTOS) +** +** Description : +** configGENERATE_RUN_TIME_STATS must be defined as 1 for this +** function to be available. The application must also then +** provide definitions for +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +** portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral +** timer/counter and return the timers current count value +** respectively. The counter should be at least 10 times the +** frequency of the tick count. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. +** Setting configGENERATE_RUN_TIME_STATS to 1 will result in a +** total accumulated execution time being stored for each task. +** The resolution of the accumulated time value depends on the +** frequency of the timer configured by the +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. Calling +** vTaskGetRunTimeStats() writes the total execution time of +** each task into a buffer, both as an absolute count value and +** as a percentage of the total system execution time. +** Parameters : +** NAME - DESCRIPTION +** pcWriteBuffer - A buffer into which +** the execution times will be written, in +** ascii form. This buffer is assumed to be +** large enough to contain the generated +** report. Approximately 40 bytes per task +** should be sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +Tsize_t FRTOS1_xPortGetFreeHeapSize(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void *pvBuffer, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ +/* +** =================================================================== +** Method : FRTOS1_OnCounterRestart (component FreeRTOS) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void RTOSCNTRLDD1_OnCounterRestart(LDD_TUserData *UserDataPtr __attribute__((unused))) +{ + FRTOS1_RunTimeCounter++; /* increment runtime counter */ +} + +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ +/* +void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : ParseCommand (component FreeRTOS) +** +** Description : +** Shell Command Line Parser +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable which tells if +** the command has been handled or not +** * io - Pointer to I/O structure +** Returns : +** --- - Error code +** =================================================================== +*/ +#if configUSE_SHELL +uint8_t FRTOS1_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io) +{ + if (UTIL1_strcmp((char*)cmd, CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, "FRTOS1 help")==0) { + *handled = TRUE; + return PrintHelp(io); + } else if ((UTIL1_strcmp((char*)cmd, CLS1_CMD_STATUS)==0) || (UTIL1_strcmp((char*)cmd, "FRTOS1 status")==0)) { + *handled = TRUE; + return PrintStatus(io); + } else if (UTIL1_strcmp((char*)cmd, "FRTOS1 tasklist")==0) { + *handled = TRUE; + return PrintTaskList(io); + } + return ERR_OK; +} +#endif + +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Init(void) +{ + portDISABLE_ALL_INTERRUPTS(); /* disable all interrupts, they get enabled in vStartScheduler() */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* enable clocking for low power timer, otherwise vPortStopTickTimer() will crash. + Additionally, Percepio trace needs access to the timer early on. */ + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); +#endif + vPortStopTickTimer(); /* tick timer shall not run until the RTOS scheduler is started */ +#if configUSE_PERCEPIO_TRACE_HOOKS + McuPercepio_Startup(); /* Startup Percepio Trace. Need to do this before calling any RTOS functions. */ +#endif +} + +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ +/* +signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCountFromISR(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void *pvItemToQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreate(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ +/* +byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet , BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ +/* +TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void *const pvTimerID, TimerCallbackFunction_t pxCallbackFunction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ +/* +void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ +/* +uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t *pxQueueBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount, StaticSemaphore_t pxSempahoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ +/* +UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if configGENERATE_RUN_TIME_STATS +void FRTOS1_AppConfigureTimerForRuntimeStats(void) +{ +#if configGENERATE_RUN_TIME_STATS_USE_TICKS + /* nothing needed, the RTOS will initialize the tick counter */ +#else + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + FRTOS1_RunTimeCounter = 0; + FRTOS1_RunTimeCounterHandle = RTOSCNTRLDD1_Init(NULL); + (void)RTOSCNTRLDD1_Enable(FRTOS1_RunTimeCounterHandle); +#endif +} + +#endif /* configGENERATE_RUN_TIME_STATS */ +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void) +{ +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + return xTaskGetTickCountFromISR(); /* using RTOS tick counter */ + #else /* using timer counter */ + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + return FRTOS1_RunTimeCounter; + #endif +#else + return 0; /* dummy value */ +#endif +} + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ +/* END FRTOS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.h new file mode 100644 index 0000000..33fce4a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1.h @@ -0,0 +1,4375 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Enabled +** Use Tick Counter : no +** LDD : Enabled +** Runtime Counter LDD : RuntimeCntrLDD +** non-LDD : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4F +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 200 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 1000 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 8192 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 4: merge free blocks +** Static Allocation : Disabled +** User Memory Section : Disabled +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Enabled +** Max number of tasks : 16 +** Shell : CLS1 +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** vTaskGetRunTimeStats - void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** ParseCommand - uint8_t FRTOS1_ParseCommand(const unsigned char *cmd, bool *handled, const... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + + +#ifndef __FRTOS1_H +#define __FRTOS1_H + +/* MODULE FRTOS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "FreeRTOSConfig.h" +#include "FRTOS1config.h" /* configuration file for component */ + +#if configUSE_SHELL + #include "CLS1.h" +#endif + +/* other includes needed */ +#include "FreeRTOS.h" +#include "task.h" /* task API */ +#include "semphr.h" /* semaphore API */ +#include "event_groups.h" /* event group API */ +#include "timers.h" /* timer module API */ +#include /* for size_t type */ + +#if configUSE_PERCEPIO_TRACE_HOOKS + #include "McuPercepio.h" /* Interface to Percepio Trace */ +#endif + +/* Macro for shell support */ +#define FRTOS1_PARSE_COMMAND_ENABLED (configUSE_SHELL) /* set to 1 if method ParseCommand() is present, 0 otherwise */ +#define FRTOS1_GENERATE_PEX_RTOS_MACROS 1 /* set to 1 to generate the RTOS macros PEX_RTOS_INIT() and PEX_RTOS_START() */ + +/* Macros used by Processor Expert */ +#if FRTOS1_GENERATE_PEX_RTOS_MACROS + #define PEX_RTOS_INIT() /* macro called from PE_low_level_init() */ \ + FRTOS1_Init(); + + #define PEX_RTOS_START() FRTOS1_vTaskStartScheduler() +#endif +/* macro to identify CPU: 0 for M0+ and 4 for M4 */ +#if configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 0 /* Cortex M0+ core */ +#elif configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 4 /* Cortex M4 core */ +#elif configCPU_FAMILY_IS_ARM_M7(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 7 /* Cortex M7 core */ +#endif + +/* Prototypes for interrupt service handlers */ +void vPortSVCHandler(void); +void vPortPendSVHandler(void); +void vPortTickHandler(void); + +/* Version of Processor Expert (variable VersionOfPEx): 1313 */ + +#ifndef __BWUserType_Tsize_t +#define __BWUserType_Tsize_t + typedef size_t Tsize_t; /* Alias to size_t standard type */ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define FRTOS1_xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) \ + xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ + +#define FRTOS1_vTaskStartScheduler() \ + vTaskStartScheduler() +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskYIELD() \ + taskYIELD() +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENTER_CRITICAL() \ + taskENTER_CRITICAL() +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskEXIT_CRITICAL() \ + taskEXIT_CRITICAL() +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskDISABLE_INTERRUPTS() \ + taskDISABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENABLE_INTERRUPTS() \ + taskENABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspendAll() \ + vTaskSuspendAll() +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeAll() \ + xTaskResumeAll() +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_vTaskDelay(xTicksToDelay) \ + vTaskDelay(xTicksToDelay) +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) \ + vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxTaskPriorityGet(pxTask) \ + uxTaskPriorityGet(pxTask) +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ + +#define FRTOS1_vTaskPrioritySet(pxTask, uxNewPriority) \ + vTaskPrioritySet(pxTask, uxNewPriority) +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeRecursive(xMutex, xBlockTime) \ + xSemaphoreTakeRecursive(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveRecursive(xMutex) \ + xSemaphoreGiveRecursive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutex() \ + xSemaphoreCreateRecursiveMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspend(pxTaskToSuspend) \ + vTaskSuspend(pxTaskToSuspend) + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskResume(pxTaskToResume) \ + vTaskResume(pxTaskToResume) + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutex() \ + xSemaphoreCreateMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTake(xMutex, xBlockTime) \ + xSemaphoreTake(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGive(xMutex) \ + xSemaphoreGive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreCreateBinary(xSemaphore) \ + vSemaphoreCreateBinary(xSemaphore) + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) \ + xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreDelete(xSemaphore) \ + vSemaphoreDelete(xSemaphore) +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskList(pcWriteBuffer, bufSize) \ + vTaskList(pcWriteBuffer, bufSize) + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvPortMalloc(xWantedSize) \ + pvPortMalloc(xWantedSize) +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ + +#define FRTOS1_vPortFree(pv) \ + vPortFree(pv) +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCount() \ + xTaskGetTickCount() +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ + +#define FRTOS1_xTaskGetSchedulerState() \ + xTaskGetSchedulerState() +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetStackHighWaterMark(xTask) \ + uxTaskGetStackHighWaterMark(xTask) +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetNumberOfTasks() \ + uxTaskGetNumberOfTasks() +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ + +#define FRTOS1_vTaskGetRunTimeStats(pcWriteBuffer, bufSize) \ + vTaskGetRunTimeStats(pcWriteBuffer, bufSize) + +/* +** =================================================================== +** Method : vTaskGetRunTimeStats (component FreeRTOS) +** +** Description : +** configGENERATE_RUN_TIME_STATS must be defined as 1 for this +** function to be available. The application must also then +** provide definitions for +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +** portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral +** timer/counter and return the timers current count value +** respectively. The counter should be at least 10 times the +** frequency of the tick count. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. +** Setting configGENERATE_RUN_TIME_STATS to 1 will result in a +** total accumulated execution time being stored for each task. +** The resolution of the accumulated time value depends on the +** frequency of the timer configured by the +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. Calling +** vTaskGetRunTimeStats() writes the total execution time of +** each task into a buffer, both as an absolute count value and +** as a percentage of the total system execution time. +** Parameters : +** NAME - DESCRIPTION +** pcWriteBuffer - A buffer into which +** the execution times will be written, in +** ascii form. This buffer is assumed to be +** large enough to contain the generated +** report. Approximately 40 bytes per task +** should be sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xPortGetFreeHeapSize() \ + xPortGetFreeHeapSize() + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xQueueCreate(uxQueueLength, uxItemSize) \ + xQueueCreate(uxQueueLength, uxItemSize) +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceive(xQueue, pvBuffer, xTicksToWait) \ + xQueueReceive(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeek(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeek(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_vQueueDelete(pxQueueToDelete) \ + vQueueDelete(pxQueueToDelete) +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaiting(xQueue) \ + uxQueueMessagesWaiting(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaitingfromISR(xQueue) \ + uxQueueMessagesWaitingfromISR(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) \ + xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) \ + xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeFromISR(pxTaskToResume) \ + xTaskResumeFromISR(pxTaskToResume) + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ + +extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ +extern LDD_TDeviceData *FRTOS1_RunTimeCounterHandle; /* runtime counter handle, used for configGENERATE_RUNTIME_STATS */ +void RTOSCNTRLDD1_OnCounterRestart(LDD_TUserData *UserDataPtr); + +#define FRTOS1_xQueueReset(xQueue) \ + xQueueReset(xQueue) + +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGetMutexHolder(xSemaphore) \ + xSemaphoreGetMutexHolder(xSemaphore) + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#if configUSE_SHELL +uint8_t FRTOS1_ParseCommand(const unsigned char *cmd, bool *handled, const CLS1_StdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component FreeRTOS) +** +** Description : +** Shell Command Line Parser +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable which tells if +** the command has been handled or not +** * io - Pointer to I/O structure +** Returns : +** --- - Error code +** =================================================================== +*/ +#endif + +void FRTOS1_Init(void); +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetCurrentTaskHandle() \ + xTaskGetCurrentTaskHandle() +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ + +#define FRTOS1_xTaskGetIdleTaskHandle() \ + xTaskGetIdleTaskHandle() +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetTaskName(xTaskToQuery) \ + pcTaskGetTaskName(xTaskToQuery) +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCountFromISR() \ + xTaskGetTickCountFromISR() +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwrite(xQueue, pvItemToQueue) \ + xQueueOverwrite(xQueue, pvItemToQueue) +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_vQueueAddToRegistry(xQueue, pcQueueName) \ + vQueueAddToRegistry(xQueue, pcQueueName) +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vQueueUnregisterQueue(xQueue) \ + vQueueUnregisterQueue(xQueue) +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueFullFromISR(xQueue) \ + xQueueIsQueueFullFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueEmptyFromISR(xQueue) \ + xQueueIsQueueEmptyFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreate() \ + xEventGroupCreate() +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) \ + xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBits(xEventGroup, uxBitsToSet) \ + xEventGroupSetBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) \ + xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBits(xEventGroup, uxBitsToSet) \ + xEventGroupClearBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) \ + xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBits(xEventGroup) \ + xEventGroupGetBits(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBitsFromISR(xEventGroup) \ + xEventGroupGetBitsFromISR(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) \ + xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) \ + xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerIsTimerActive(xTimer) \ + xTimerIsTimerActive(xTimer) +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerStart(xTimer, xBlockTime) \ + xTimerStart(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStop(xTimer, xBlockTime) \ + xTimerStop(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) \ + xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerDelete(xTimer, xBlockTime) \ + xTimerDelete(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerReset(xTimer, xBlockTime) \ + xTimerReset(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) \ + xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_pvTimerGetTimerID(xTimer) \ + pvTimerGetTimerID(xTimer) +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ + +#define FRTOS1_xTimerGetTimerDaemonTaskHandle() \ + xTimerGetTimerDaemonTaskHandle() +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ + +#define FRTOS1_pcTimerGetTimerName(xTimer) \ + pcTimerGetTimerName(xTimer) +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) \ + xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) \ + xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyGive(xTaskToNotify) \ + xTaskNotifyGive(xTaskToNotify) \ +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ + +#define FRTOS1_ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) \ + ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ + +#define FRTOS1_vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) \ + vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskNotify(xTaskToNotify, ulValue, eAction) \ + xTaskNotify(xTaskToNotify, ulValue, eAction) +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) \ + xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) \ + xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ + +#define FRTOS1_vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) \ + vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) \ + pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinary() \ + xSemaphoreCreateBinary() +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) \ + xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) \ + xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyStateClear(xTask) \ + xTaskNotifyStateClear(xTask) +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +void FRTOS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetHandle(pcNameToQuery) \ + xTaskGetHandle(pcNameToQuery) + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetName(xTaskToQuery) \ + pcTaskGetName(xTaskToQuery) + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ + +#define FRTOS1_xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) \ + xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ + +#define FRTOS1_xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) \ + xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreateStatic(pxEventGroupBuffer) \ + xEventGroupCreateStatic(pxEventGroupBuffer) + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) \ + xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) \ + xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateMutexStatic(pxMutexBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) \ + vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxSemaphoreGetCount(xSemaphore) \ + uxSemaphoreGetCount(xSemaphore) +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +void FRTOS1_AppConfigureTimerForRuntimeStats(void); +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ + +/* END FRTOS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __FRTOS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1config.h new file mode 100644 index 0000000..ba493d6 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FRTOS1config.h @@ -0,0 +1,155 @@ +#ifndef __FRTOS1_CONFIG_H +#define __FRTOS1_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ + +/* -------------------------------------------------------------------- */ +/* Macros to identify the compiler used: */ +#define configCOMPILER_ARM_GCC 1 /* GNU ARM gcc compiler */ +#define configCOMPILER_ARM_IAR 2 /* IAR ARM compiler */ +#define configCOMPILER_ARM_FSL 3 /* Legacy Freescale ARM compiler */ +#define configCOMPILER_ARM_KEIL 4 /* ARM/Keil compiler */ +#define configCOMPILER_S08_FSL 5 /* Freescale HCS08 compiler */ +#define configCOMPILER_S12_FSL 6 /* Freescale HCS12(X) compiler */ +#define configCOMPILER_CF1_FSL 7 /* Freescale ColdFire V1 compiler */ +#define configCOMPILER_CF2_FSL 8 /* Freescale ColdFire V2 compiler */ +#define configCOMPILER_DSC_FSL 9 /* Freescale DSC compiler */ + +#define configCOMPILER configCOMPILER_ARM_GCC +/* -------------------------------------------------------------------- */ +/* CPU family identification */ +#define configCPU_FAMILY_S08 1 /* S08 core */ +#define configCPU_FAMILY_S12 2 /* S12(X) core */ +#define configCPU_FAMILY_CF1 3 /* ColdFire V1 core */ +#define configCPU_FAMILY_CF2 4 /* ColdFire V2 core */ +#define configCPU_FAMILY_DSC 5 /* 56800/DSC */ +#define configCPU_FAMILY_ARM_M0P 6 /* ARM Cortex-M0+ */ +#define configCPU_FAMILY_ARM_M3 7 /* ARM Cortex-M3 */ +#define configCPU_FAMILY_ARM_M4 8 /* ARM Cortex-M4 */ +#define configCPU_FAMILY_ARM_M4F 9 /* ARM Cortex-M4F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M7 10 /* ARM Cortex-M7 */ +#define configCPU_FAMILY_ARM_M7F 11 /* ARM Cortex-M7F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M33 12 /* ARM Cortex-M33 */ +#define configCPU_FAMILY_ARM_M33F 13 /* ARM Cortex-M33F (with floating point unit) */ +#define configCPU_FAMILY_RISC_V 14 /* RISC-V */ + +/* Macros to identify set of core families */ +#define configCPU_FAMILY_IS_ARM_M0(fam) ((fam)==configCPU_FAMILY_ARM_M0P) +#define configCPU_FAMILY_IS_ARM_M3(fam) ((fam)==configCPU_FAMILY_ARM_M3) +#define configCPU_FAMILY_IS_ARM_M4(fam) (((fam)==configCPU_FAMILY_ARM_M4) || ((fam)==configCPU_FAMILY_ARM_M4F)) +#define configCPU_FAMILY_IS_ARM_M7(fam) (((fam)==configCPU_FAMILY_ARM_M7) || ((fam)==configCPU_FAMILY_ARM_M7F)) +#define configCPU_FAMILY_IS_ARM_M4_M7(fam) (configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam)) +#define configCPU_FAMILY_IS_ARM_M33(fam) (((fam)==configCPU_FAMILY_ARM_M33) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM_FPU(fam) (((fam)==configCPU_FAMILY_ARM_M4F) || ((fam)==configCPU_FAMILY_ARM_M7F) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM(fam) (configCPU_FAMILY_IS_ARM_M0(fam) || configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam) || configCPU_FAMILY_IS_ARM_M33(fam)) + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* determine core based on library configuration */ + #if MCUC1_CONFIG_CORTEX_M==0 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M0P + #elif MCUC1_CONFIG_CORTEX_M==3 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M3 + #elif MCUC1_CONFIG_CORTEX_M==4 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4F + #elif MCUC1_CONFIG_CORTEX_M==4 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4 + #elif MCUC1_CONFIG_CORTEX_M==7 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7F + #elif MCUC1_CONFIG_CORTEX_M==7 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7 + #elif MCUC1_CONFIG_CORTEX_M==33 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33F + #elif MCUC1_CONFIG_CORTEX_M==33 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33 + #else + #error "unsupported configuaration!" + #endif +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configCPU_FAMILY configCPU_FAMILY_RISC_V +#else /* default CPU family */ + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4F +#endif + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0 && (configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY)||configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY))) + /*!< 1: enable MPU support; 0: MPU support is disabled */ +#endif + +#ifndef configENABLE_FPU + #define configENABLE_FPU (1 && MCUC1_CONFIG_FPU_PRESENT) + /*!< 1: enable FPU support; 0: FPU support is disabled */ +#endif + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0 && configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) + /*!< 1: enable ARM TrustZone support; 0: TrustZone support is disabled */ +#endif + +/*----------------------------------------------------------- + * GDB backtrace handler support + * See http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + *----------------------------------------------------------*/ +#ifndef configGDB_HELPER + #define configGDB_HELPER (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GDB stack backtrace debug helper; 0: disabled */ +#endif + +#ifndef configLTO_HELPER + #define configLTO_HELPER (1 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GNU Link Time Optimizer (-lto) debug helper code; 0: disabled */ +#endif + +#ifndef configHEAP_SCHEME_IDENTIFICATION + #define configHEAP_SCHEME_IDENTIFICATION (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: use constant freeRTOSMemoryScheme to identify memory scheme; 0: no constant used */ +#endif + +#ifndef configUSE_TOP_USED_PRIORITY + #define configUSE_TOP_USED_PRIORITY (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: Makes sure uxTopUsedPriority is present (needed for SEGGER and OpenOCD thread aware debugging); 0: no special reference to uxTopUsedPriority */ +#endif + +#ifndef configLINKER_HEAP_BASE_SYMBOL + #define configLINKER_HEAP_BASE_SYMBOL __HeapBase + /*!< Linker symbol used to denote the base address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapBase, MCUXpresso: _pvHeapStart) */ +#endif + +#ifndef configLINKER_HEAP_LIMIT_SYMBOL + #define configLINKER_HEAP_LIMIT_SYMBOL __HeapLimit + /*!< Linker symbol used to denote the limit address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapLimit, MCUXpresso: _pvHeapLimit) */ +#endif + +#ifndef configLINKER_HEAP_SIZE_SYMBOL + #define configLINKER_HEAP_SIZE_SYMBOL __heap_size + /*!< Linker symbol used to denote the size of the heap, used for heap memory scheme 6 (newlib). (KDS: __heap_size, MCUXpresso: _HeapSize) */ +#endif + +#ifndef configUSE_SHELL + #define configUSE_SHELL (1) + /*!< 1: enable Shell and command line support; 0: disabled */ +#endif + +#ifndef configRESET_MSP + #define configRESET_MSP (1) + /*!< 1: reset MSP at scheduler start (Cortex M3/M4/M7 only); 0: do not reset MSP */ +#endif + + +/*----------------------------------------------------------- + * FreeRTOS Trace hook support + *----------------------------------------------------------- */ +#ifndef configUSE_PERCEPIO_TRACE_HOOKS + #define configUSE_PERCEPIO_TRACE_HOOKS 0 /* 1: Percepio Trace hooks, 0: not using Percepio Trace hooks */ +#endif +#define configUSE_TRACE_HOOKS configUSE_PERCEPIO_TRACE_HOOKS /* legacy configUSE_TRACE_HOOKS should not be used any more */ + +#ifndef configUSE_SEGGER_SYSTEM_VIEWER_HOOKS + #define configUSE_SEGGER_SYSTEM_VIEWER_HOOKS 0 /* 1: Segger System Viewer hooks, 0: not using Segger System Viewer hooks */ +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configUSE_PERCEPIO_TRACE_HOOKS + #error "only one trace method can be active!" +#endif +/*----------------------------------------------------------- */ + +#endif /* __FRTOS1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FSL_USB_Stack_Config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FSL_USB_Stack_Config.h new file mode 100644 index 0000000..72657ff --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FSL_USB_Stack_Config.h @@ -0,0 +1,12 @@ +/****************************************************************************** + * Configuration file for the FSL USB stack created with Processor Expert. + *****************************************************************************/ +#ifndef __FSL_USB_STACK_CONFIG_ +#define __FSL_USB_STACK_CONFIG_ + +/* Overwrite initialization values from Processor Expert Init() component. These are 'known working values'. + * Otherwise you have to setup the bits (e.g. Pull-up/pull-down resistors! + * */ +#define USB_USER_CONFIG_USE_STACK_INIT 1 /* value set by component property 'Use USB Stack Initialization' */ + +#endif /* __FSL_USB_STACK_CONFIG_ */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS.h new file mode 100644 index 0000000..ec88675 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS.h @@ -0,0 +1,1320 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +//#include /* READ COMMENT ABOVE. */ /*<< EST */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +// #include /* READ COMMENT ABOVE. */ /* << EST */ +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "SIM_PDD.h" /*! \todo this is a PEx header */ +#endif + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + #include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 + #define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +#ifndef portMEMORY_BARRIER + #define portMEMORY_BARRIER() +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + #include "SEGGER_SYSVIEW_FreeRTOS.h" /* include Segger System Viewer macro definitions */ +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H + #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#if 1 /* << EST additional trace entries used by Segger SystemView */ + +#ifndef traceISR_ENTER + #define traceISR_ENTER() +#endif + +#ifndef traceISR_EXIT_TO_SCHEDULER + #define traceISR_EXIT_TO_SCHEDULER() +#endif + +#ifndef traceISR_EXIT + #define traceISR_EXIT() +#endif + +#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST + #define traceMOVED_TASK_TO_SUSPENDED_LIST(x) +#endif + +#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST + #define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() +#endif + +#ifndef traceMOVED_TASK_TO_DELAYED_LIST + #define traceMOVED_TASK_TO_DELAYED_LIST() +#endif + +#endif /* << EST */ + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING + #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portALLOCATE_SECURE_CONTEXT + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) +#endif + +#ifndef portDONT_DISCARD + #define portDONT_DISCARD +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configUSE_POSIX_ERRNO + #define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#ifndef configSTACK_DEPTH_TYPE + /* Defaults to uint16_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if uint16_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE + /* Defaults to size_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if lengths will always be less than the number of bytes + in a size_t. */ + #define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #if( INCLUDE_vTaskSuspend != 1 ) + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT + #define configINITIAL_TICK_COUNT 0 +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or + portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + /* The tick type can be read atomically, so critical sections used when the + tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF + /* configPRINTF() was not defined, so define it away to nothing. To use + configPRINTF() then define it as follows (where MyPrintFunction() is + provided by the application writer): + + void MyPrintFunction(const char *pcFormat, ... ); + #define configPRINTF( X ) MyPrintFunction X + + Then call like a standard printf() function, but placing brackets around + all parameters so they are passed as a single parameter. For example: + configPRINTF( ("Value = %d", MyVariable) ); */ + #define configPRINTF( X ) +#endif + +#ifndef configMAX + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t + + /* For libraries that break the list data hiding, and access list structure + members directly (which is not supposed to be done). */ + #define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_MPU + #define configENABLE_MPU 0 +#endif + +/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif + +/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. +This is currently used in ARMv8M ports. */ +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE 1 +#endif + +/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on +the Secure Side only. */ +#ifndef configRUN_FREERTOS_SECURE_ONLY + #define configRUN_FREERTOS_SECURE_ONLY 0 +#endif + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using + * dynamically allocated RAM, in which case when any task is deleted it is known + * that both the task's stack and TCB need to be freed. Sometimes the + * FreeRTOSConfig.h settings only allow a task to be created using statically + * allocated RAM, in which case when any task is deleted it is known that neither + * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h + * settings allow a task to be created using either statically or dynamically + * allocated RAM, in which case a member of the TCB is used to record whether the + * stack and/or TCB were allocated statically or dynamically, so when a task is + * deleted the RAM that was allocated dynamically is freed again and no attempt is + * made to free the RAM that was allocated statically. + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a + * task to be created using either statically or dynamically allocated RAM. Note + * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with + * a statically allocated stack and a dynamically allocated TCB. + * + * The following table lists various combinations of portUSING_MPU_WRAPPERS, + * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and + * when it is possible to have both static and dynamic allocation: + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | + * | | | | | | Static Possible | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | + * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ + ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 4 ]; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; + #endif +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + UBaseType_t uxDummy2; + void *pvDummy3; + StaticMiniListItem_t xDummy4; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; + #endif +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; + #endif + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void *pvDummy5; + TaskFunction_t pvDummy6; + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + uint8_t ucDummy8; + +} StaticTimer_t; + +/* +* In line with software engineering best practice, especially when supplying a +* library that is likely to change in future versions, FreeRTOS implements a +* strict data hiding policy. This means the stream buffer structure used +* internally by FreeRTOS is not accessible to application code. However, if +* the application writer wants to statically allocate the memory required to +* create a stream buffer then the size of the stream buffer object needs to be +* know. The StaticStreamBuffer_t structure below is provided for this purpose. +* Its size and alignment requirements are guaranteed to match those of the +* genuine structure, no matter which architecture is being used, and no matter +* how the values in FreeRTOSConfig.h are set. Its contents are somewhat +* obfuscated in the hope users will recognise that it would be unwise to make +* direct use of the structure members. +*/ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* << EST */ + #include "trcRecorder.h" +#endif + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOSConfig.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOSConfig.h new file mode 100644 index 0000000..81147d1 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOSConfig.h @@ -0,0 +1,305 @@ +/* + * FreeRTOS Kernel V10.1.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ +#include "FRTOS1config.h" /* extra configuration settings not part of the original FreeRTOS ports */ + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 /* 1: include additional header file at the end of task.c to help with debugging in GDB in combination with configUSE_TRACE_FACILITY; 0: no extra file included. */ +#define configENABLE_BACKWARD_COMPATIBILITY 0 /* 1: enable backward compatibility mode, using old names in kernel. 0: use new kernel structure names (recommended) */ +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ +#ifndef configGENERATE_RUN_TIME_STATS_USE_TICKS + #define configGENERATE_RUN_TIME_STATS_USE_TICKS 0 /* 1: Use the RTOS tick counter as runtime counter. 0: use extra timer */ +#endif +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 1 /* 1: generate runtime statistics; 0: no runtime statistics */ +#endif +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ /* default: use Tick counter as runtime counter */ + #define portGET_RUN_TIME_COUNTER_VALUE() xTaskGetTickCountFromISR() /* default: use Tick counter as runtime counter */ + #else /* use dedicated timer */ + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() FRTOS1_AppConfigureTimerForRuntimeStats() + #define portGET_RUN_TIME_COUNTER_VALUE() FRTOS1_AppGetRuntimeCounterValueFromISR() + #endif +#else /* no runtime stats, use empty macros */ + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ + #define portGET_RUN_TIME_COUNTER_VALUE() /* nothing */ +#endif +#define configUSE_PREEMPTION 1 /* 1: pre-emptive mode; 0: cooperative mode */ +#define configUSE_TIME_SLICING 1 /* 1: use time slicing; 0: don't time slice at tick interrupt time */ +#define configUSE_IDLE_HOOK 1 /* 1: use Idle hook; 0: no Idle hook */ +#define configUSE_IDLE_HOOK_NAME FRTOS1_vApplicationIdleHook +#define configUSE_TICK_HOOK 1 /* 1: use Tick hook; 0: no Tick hook */ +#define configUSE_TICK_HOOK_NAME FRTOS1_vApplicationTickHook +#define configUSE_MALLOC_FAILED_HOOK 1 /* 1: use MallocFailed hook; 0: no MallocFailed hook */ +#define configUSE_MALLOC_FAILED_HOOK_NAME FRTOS1_vApplicationMallocFailedHook +#ifndef configTICK_RATE_HZ + #define configTICK_RATE_HZ (1000) /* frequency of tick interrupt */ +#endif +#define configSYSTICK_USE_LOW_POWER_TIMER 0 /* If using Kinetis Low Power Timer (LPTMR) instead of SysTick timer */ +#define configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ 1 /* 1 kHz LPO timer. Set to 1 if not used */ +#if MCUC1_CONFIG_NXP_SDK_USED || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_GENERIC || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_NORDIC_NRF5 +/* The CMSIS variable SystemCoreClock contains the current clock speed */ + extern uint32_t SystemCoreClock; + #define configCPU_CLOCK_HZ SystemCoreClock /* CPU clock frequency */ + #define configBUS_CLOCK_HZ SystemCoreClock /* Bus clock frequency */ +#else + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) /* Kinetis defines this one in Cpu.h */ + #define configCPU_CLOCK_HZ CPU_CORE_CLK_HZ /* CPU core clock defined in Cpu.h */ + #else + #define configCPU_CLOCK_HZ CPU_INSTR_CLK_HZ /* CPU core clock defined in Cpu.h */ + #endif + #define configBUS_CLOCK_HZ CPU_BUS_CLK_HZ /* CPU bus clock defined in Cpu.h */ +#endif /* #if MCUC1_CONFIG_NXP_SDK_USED */ +#define configSYSTICK_USE_CORE_CLOCK 1 /* System Tick is using core clock */ +#define configSYSTICK_CLOCK_DIVIDER 1 /* no divider */ +#define configSYSTICK_CLOCK_HZ ((configCPU_CLOCK_HZ)/configSYSTICK_CLOCK_DIVIDER) /* frequency of system tick counter */ +#ifndef configMINIMAL_STACK_SIZE + #define configMINIMAL_STACK_SIZE (200) /* stack size in addressable stack units */ +#endif +/*----------------------------------------------------------*/ +/* Heap Memory */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 4 /* either 1 (only alloc), 2 (alloc/free), 3 (malloc), 4 (coalesc blocks), 5 (multiple blocks), 6 (newlib) */ +#endif /* configUSE_HEAP_SCHEME */ +#define configFRTOS_MEMORY_SCHEME configUSE_HEAP_SCHEME /* for backwards compatible only with legacy name */ +#ifndef configTOTAL_HEAP_SIZE + #define configTOTAL_HEAP_SIZE (8192) /* size of heap in bytes */ +#endif /* configTOTAL_HEAP_SIZE */ +#ifndef configUSE_HEAP_SECTION_NAME + #define configUSE_HEAP_SECTION_NAME 0 /* set to 1 if a custom section name (configHEAP_SECTION_NAME_STRING) shall be used, 0 otherwise */ +#endif +#ifndef configHEAP_SECTION_NAME_STRING + #define configHEAP_SECTION_NAME_STRING ".m_data_20000000" /* heap section name (use e.g. ".m_data_20000000" for KDS/gcc, ".bss.$SRAM_LOWER.FreeRTOS" for MCUXpresso or "m_data_20000000" for IAR). Check your linker file for the name used. */ +#endif +#define configAPPLICATION_ALLOCATED_HEAP 0 /* set to one if application is defining heap ucHeap[] variable, 0 otherwise */ +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* 1: make dynamic allocation functions for RTOS available. 0: only static functions are allowed */ +#endif +#ifndef configSUPPORT_STATIC_ALLOCATION + #define configSUPPORT_STATIC_ALLOCATION 0 /* 1: make static allocation functions for RTOS available. 0: only dynamic functions are allowed */ +#endif +#define configUSE_NEWLIB_REENTRANT (configUSE_HEAP_SCHEME==6) /* 1: a newlib reent structure will be allocated for each task; 0: no such reentr structure used */ +/*----------------------------------------------------------*/ +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 12 /* task name length in bytes */ +#endif +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 1 /* 1: include additional structure members and functions to assist with execution visualization and tracing, 0: no runtime stats/trace */ +#endif +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS (configUSE_TRACE_FACILITY || configGENERATE_RUN_TIME_STATS) +#endif +#define configUSE_16_BIT_TICKS 0 /* 1: use 16bit tick counter type, 0: use 32bit tick counter type */ +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 /* 1: the IDEL task will yield as soon as possible. 0: The IDLE task waits until preemption. */ +#endif +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION (1 && configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY)) /* 1: the scheduler uses an optimized task selection as defined by the port (if available). 0: normal task selection is used */ +#endif +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 1 +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 1 /* 0 is disabling stack overflow. Set it to 1 for Method1 or 2 for Method2 */ +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW_NAME + #define configCHECK_FOR_STACK_OVERFLOW_NAME FRTOS1_vApplicationStackOverflowHook +#endif +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 1 +#endif +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 5 +#endif +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 1 +#endif +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif +/* Tickless Idle Mode ----------------------------------------------------------*/ +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 /* set to 1 for tickless idle mode, 0 otherwise */ +#endif +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 /* number of ticks must be larger than this to enter tickless idle mode */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK + #define configUSE_TICKLESS_IDLE_DECISION_HOOK 0 /* set to 1 to enable application hook, zero otherwise */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME + #define configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME xEnterTicklessIdle /* function name of decision hook */ +#endif +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 /* number of tread local storage pointers, 0 to disable functionality */ +#endif + +#ifndef configMAX_PRIORITIES + #define configMAX_PRIORITIES 6 /* task priorities can be from 0 up to this value-1 */ +#endif +#define configMAX_CO_ROUTINE_PRIORITIES 2 /* co-routine priorities can be from 0 up to this value-1 */ + +/* the following needs to be defined (present) or not (not present)! */ +#define configTASK_RETURN_ADDRESS 0 /* return address of task is zero */ + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 1 /* 1: record stack high address for the debugger, 0: do not record stack high address */ +#endif + +/* Software timer definitions. */ +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_TASK_PRIORITY + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_QUEUE_LENGTH + #define configTIMER_QUEUE_LENGTH 10U /* size of queue for the timer task */ +#endif +#ifndef configTIMER_TASK_STACK_DEPTH + #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE) +#endif +#ifndef INCLUDE_xEventGroupSetBitFromISR + #define INCLUDE_xEventGroupSetBitFromISR 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 /* 1: use application specific vApplicationDaemonTaskStartupHook(), 0: do not use hook */ +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#define configUSE_TASK_FPU_SUPPORT 1 + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ +#define INCLUDE_vTaskEndScheduler 0 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_pcTaskGetTaskName 1 +/* -------------------------------------------------------------------- */ +#define INCLUDE_pxTaskGetStackStart (1 && configUSE_SEGGER_SYSTEM_VIEWER_HOOKS) +/* -------------------------------------------------------------------- */ +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* Cortex-M specific definitions. */ + #if configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define configPRIO_BITS 4 /* 4 bits/16 priority levels on ARM Cortex M4 (Kinetis K Family) */ + #else + #define configPRIO_BITS 2 /* 2 bits/4 priority levels on ARM Cortex M0+ (Kinetis L Family) */ + #endif + + /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ + #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + + /* The highest interrupt priority that can be used by any interrupt service + routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + PRIORITY THAN THIS! (higher priorities are lower numeric values on an ARM Cortex-M). */ + #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + + /* Interrupt priorities used by the kernel port layer itself. These are generic + to all Cortex-M ports, and do not rely on any particular library functions. */ + #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) + + /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ + #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configKERNEL_INTERRUPT_PRIORITY (7) +#endif + +/* Normal assert() semantics without relying on the provision of an assert.h header file. */ +#define configASSERT(x) if((x)==0) { taskDISABLE_INTERRUPTS(); for( ;; ); } +#if 0 /* version for RISC-V with a debug break: */ +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); } +#endif + +/* RISC-V only: If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. + Otherwise set configCLINT_BASE_ADDRESS to 0. + */ +#define configCLINT_BASE_ADDRESS 0x0 + +/*---------------------------------------------------------------------------------------*/ +/* MPU and TrustZone settings */ +#ifndef configENABLE_FPU + #define configENABLE_FPU (0) +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0) +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0) +#endif /* configENABLE_TRUSTZONE */ +/*---------------------------------------------------------------------------------------*/ + +/* custom include file: */ +// #include "CustomFreeRTOSSettings.h + + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS_license.txt b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS_license.txt new file mode 100644 index 0000000..a4aa909 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/FreeRTOS_license.txt @@ -0,0 +1,38 @@ +The FreeRTOS kernel is released under the MIT open source license, the text of +which is provided below. + +This license covers the FreeRTOS kernel source files, which are located in the +/FreeRTOS/Source directory of the official FreeRTOS kernel download. It also +covers most of the source files in the demo application projects, which are +located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The +demo projects may also include third party software that is not part of FreeRTOS +and is licensed separately to FreeRTOS. Examples of third party software +includes header files provided by chip or tools vendors, linker scripts, +peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS +directory is either open source or distributed with permission, and is free for +use. For the avoidance of doubt, refer to the comments at the top of each +source file. + + +License text: +------------- + +Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +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. + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/IO_Map.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/IO_Map.h new file mode 100644 index 0000000..6936639 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/IO_Map.h @@ -0,0 +1,79 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : IO_Map.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : IO_Map +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file IO_Map.h +** @version 01.00 +** @brief +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +*/ +/*! +** @addtogroup IO_Map_module IO_Map module documentation +** @{ +*/ + +#ifndef __IO_Map_H +#define __IO_Map_H + +#include "MK22F51212.h" + +#endif +/* __IO_Map_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Init_Config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Init_Config.h new file mode 100644 index 0000000..6e4015e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Init_Config.h @@ -0,0 +1,288 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : MK22FN512LH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K22P121M120SF7RM, Rev. 1, March 24, 2014 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This file collects Processor Expert components configuration +** and interface files. +** Settings : +** Component name : Cpu +** CPU type : MK22FN512VLH12 +** CPU : CPU +** MemModelDev : MemModel_NoFlexMem +** Clock settings : +** Clock sources : +** Internal oscillator : +** Slow internal reference clock [kHz] : 32.768 +** Initialize slow trim value : no +** Fast internal reference clock [MHz] : 4 +** Initialize fast trim value : no +** RTC oscillator : Disabled +** System oscillator 0 : Enabled +** Clock source : External crystal +** Clock input pin : +** Pin name : EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 +** Clock output pin : +** Pin name : XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1 +** Clock frequency [MHz] : 8 +** Capacitor load : 0pF +** Oscillator operating mode : Low power +** Clock source settings : 1 +** Clock source setting 0 : +** Internal reference clock : +** MCGIRCLK clock : Enabled +** MCGIRCLK in stop : Disabled +** MCGIRCLK source : Slow +** MCGIRCLK clock [MHz] : 0.032768 +** External reference clock : +** OSC0ERCLK clock : Enabled +** OSC0ERCLK in stop : Disabled +** OSC0ERCLK clock [MHz] : 8 +** ERCLK32K clock source : Auto select +** ERCLK32K. clock [kHz] : 0.001 +** MCG settings : +** MCG mode : PEE +** MCG output clock : PLL clock +** MCG output [MHz] : 120 +** MCG external ref. clock source : System oscillator 0 +** MCG external ref. clock [MHz] : 8 +** Clock monitor : Disabled +** FLL settings : +** FLL module : Disabled +** FLL output [MHz] : 0 +** MCGFFCLK clock [kHz] : 31.25 +** Reference clock source : External clock +** Reference clock divider : Auto select +** FLL reference clock [kHz] : 31.25 +** Multiplication factor : Auto select +** PLL 0 settings : +** PLL module : Enabled +** PLL module in Stop : Disabled +** PLL output [MHz] : 120 +** Reference clock divider : Auto select +** PLL reference clock [MHz] : 4 +** Multiplication factor : Auto select +** Loss of lock interrupt : Disabled +** Clock configurations : 1 +** Clock configuration 0 : +** __IRC_32kHz : 0.032768 +** __IRC_4MHz : 2 +** __SYSTEM_OSC : 8 +** __RTC_OSC : 0 +** Very low power mode : Disabled +** Clock source setting : configuration 0 +** MCG mode : PEE +** MCG output [MHz] : 120 +** MCGIRCLK clock [MHz] : 0.032768 +** OSCERCLK clock [MHz] : 8 +** ERCLK32K. clock [kHz] : 0.001 +** MCGFFCLK [kHz] : 31.25 +** System clocks : +** Core clock prescaler : Auto select +** Core clock : 120 +** Bus clock prescaler : Auto select +** Bus clock : 60 +** External clock prescaler : Auto select +** External bus clock : 60 +** Flash clock prescaler : Auto select +** Flash clock : 24 +** PLL/FLL clock selection : Auto select +** Clock frequency [MHz] : 120 +** Low power mode settings : +** Allowed power modes : +** High speed run mode : Allowed +** Very low power modes : Not allowed +** Low leakage stop mode : Not allowed +** Very low leakage stop mode : Not allowed +** Operation mode settings : +** WAIT operation mode : +** Return to wait after ISR : no +** SLEEP operation mode : +** Low Power mode : STOP +** Return to stop after ISR : no +** STOP operation mode : Disabled +** External memory settings : Disabled +** Common settings : +** Initialization priority : minimal priority +** Watchdog disable : yes +** Utilize after reset values : default +** NMI pin : Enabled +** NMI Pin : PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b +** Reset pin : Enabled +** Reset Pin : RESET_b +** Debug interface (JTAG) : +** JTAG Mode : JTAG +** TDI : Enabled +** TDI Pin : PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI +** TDO : Enabled +** TDO Pin : PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO +** TCK : Enabled +** TCK Pin : PTA0/UART0_CTS_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK +** TMS : Enabled +** TMS Pin : PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO +** nTRST : Disabled +** Flash memory organization : +** Flash blocks : 2 +** Flash block 0 : PFlash +** Address : 0x0 +** Size : 262144 +** Write unit size : 4 +** Erase unit size : 2048 +** Protection unit size : 16384 +** Flash block 1 : PFlash +** Address : 0x40000 +** Size : 262144 +** Write unit size : 4 +** Erase unit size : 2048 +** Protection unit size : 16384 +** Flash configuration field : Enabled +** Security settings : +** Flash security : Disabled +** Freescale failure analysis access : Enabled +** Mass erase : Enabled +** Backdoor key security : Disabled +** Backdoor key 0 : 255 +** Backdoor key 1 : 255 +** Backdoor key 2 : 255 +** Backdoor key 3 : 255 +** Backdoor key 4 : 255 +** Backdoor key 5 : 255 +** Backdoor key 6 : 255 +** Backdoor key 7 : 255 +** Protection regions : +** P-Flash protection settings : +** Protection region size : 16384 +** P-Flash protection : 0xFFFFFFFF +** Protection regions : +** Protection region 0 : Unprotected +** Protection region 1 : Unprotected +** Protection region 2 : Unprotected +** Protection region 3 : Unprotected +** Protection region 4 : Unprotected +** Protection region 5 : Unprotected +** Protection region 6 : Unprotected +** Protection region 7 : Unprotected +** Protection region 8 : Unprotected +** Protection region 9 : Unprotected +** Protection region 10 : Unprotected +** Protection region 11 : Unprotected +** Protection region 12 : Unprotected +** Protection region 13 : Unprotected +** Protection region 14 : Unprotected +** Protection region 15 : Unprotected +** Protection region 16 : Unprotected +** Protection region 17 : Unprotected +** Protection region 18 : Unprotected +** Protection region 19 : Unprotected +** Protection region 20 : Unprotected +** Protection region 21 : Unprotected +** Protection region 22 : Unprotected +** Protection region 23 : Unprotected +** Protection region 24 : Unprotected +** Protection region 25 : Unprotected +** Protection region 26 : Unprotected +** Protection region 27 : Unprotected +** Protection region 28 : Unprotected +** Protection region 29 : Unprotected +** Protection region 30 : Unprotected +** Protection region 31 : Unprotected +** Peripheral settings : +** NMI function : Enabled +** FLASH initialization speed : Fast +** EzPort operation at boot : Enabled +** Low power boot : Disabled +** CPU interrupts/resets : +** Non-maskable interrupt : Enabled +** Interrupt : INT_NMI +** Hard fault : Disabled +** Supervisor call : Disabled +** Pendable service : Disabled +** MCG Loss of lock : Disabled +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.h +** @version 01.00 +** @brief +** This file collects Processor Expert components configuration +** and interface files. +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +#ifndef __Init_Config_H +#define __Init_Config_H + +/* MODULE Init_Config.h */ + +/* Processor Expert types and constants */ +#include "PE_Types.h" + +/* Processor configuration file */ +#include "CPU_Config.h" + +/* PinSettings component header file */ +#include "Pins1.h" + +/* Initialization component configuration header file */ +#include "USB0_Config.h" +/* Initialization component static header file */ +#include "USB0_Init.h" +/* Initialization component generated header file */ +#include "USB0.h" + + +#endif /* __Init_Config_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.c new file mode 100644 index 0000000..6d8a380 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.c @@ -0,0 +1,713 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KIN1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : KinetisTools +** Version : Component 01.041, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** +** Settings : +** Component name : KIN1 +** Utility : UTIL1 +** SDK : MCUC1 +** Shell : Enabled +** Shell : CLS1 +** Contents : +** SoftwareReset - void KIN1_SoftwareReset(void); +** UIDGet - uint8_t KIN1_UIDGet(KIN1_UID *uid); +** UIDSame - bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +** UIDtoString - uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +** GetKinetisFamilyString - KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +** GetPC - void* KIN1_GetPC(void); +** GetSP - void* KIN1_GetSP(void); +** SetPSP - void KIN1_SetPSP(void *setval); +** SetLR - void KIN1_SetLR(uint32_t setval); +** InitCycleCounter - void KIN1_InitCycleCounter(void); +** ResetCycleCounter - void KIN1_ResetCycleCounter(void); +** EnableCycleCounter - void KIN1_EnableCycleCounter(void); +** DisableCycleCounter - void KIN1_DisableCycleCounter(void); +** GetCycleCounter - uint32_t KIN1_GetCycleCounter(void); +** ParseCommand - uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const... +** Deinit - void KIN1_Deinit(void); +** Init - void KIN1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KIN1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KIN1_module KIN1 module documentation +** @{ +*/ + +/* MODULE KIN1. */ + +#include "KIN1.h" + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +#include "UTIL1.h" /* various utility functions */ +#if MCUC1_CONFIG_NXP_SDK_2_0_USED + #include "fsl_common.h" + #if MCUC1_CONFIG_CPU_IS_KINETIS + #include "fsl_sim.h" /* system integration module, used for CPU ID */ + #endif +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3 + #include "Cpu.h" /* include CPU related interfaces and defines */ +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K + #include "Cpu.h" /* include CPU related interfaces and defines */ +#elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* include device specific header file for CMSIS inside "KIN1config.h" */ +#endif + +#if MCUC1_CONFIG_CPU_IS_KINETIS +#if MCUC1_CONFIG_CORTEX_M==4 +static const unsigned char *KinetisM4FamilyStrings[] = +{ /* FAMID (3 bits) are used as index */ + (const unsigned char *)"K10 or K12 Family", /* 000 */ + (const unsigned char *)"K20 or K22 Family", /* 001 */ + (const unsigned char *)"K30, K11 or K61 Family", /* 010 */ + (const unsigned char *)"K40 or K21 Family", /* 011 */ + (const unsigned char *)"K60 or K62 Family", /* 100 */ + (const unsigned char *)"K70 Family", /* 101 */ + (const unsigned char *)"Reserved", /* 110 */ + (const unsigned char *)"Reserved" /* 111 */ +}; +#endif + +#if MCUC1_CONFIG_CORTEX_M==0 +static const unsigned char *KinetisM0FamilyStrings[] = +{ /* FAMID (3 bits) are used as index */ + (const unsigned char *)"KL0x", /* 0000 */ + (const unsigned char *)"KL1x", /* 0001 */ + (const unsigned char *)"KL2x", /* 0010 */ + (const unsigned char *)"KL3x", /* 0011 */ + (const unsigned char *)"KL4x", /* 0100 */ + (const unsigned char *)"Reserved", /* 0101 */ + (const unsigned char *)"Reserved", /* 0110 */ + (const unsigned char *)"Reserved" /* 0111 */ +}; +#endif +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +static uint8_t PrintStatus(const CLS1_StdIOType *io) +{ +#if MCUC1_CONFIG_CPU_IS_KINETIS + uint8_t buf[1+(16*5)+1+1]; /* "{0xAA,...0xBB}" */ + uint8_t res; + KIN1_UID uid; +#endif + + CLS1_SendStatusStr((unsigned char*)"KIN1", (unsigned char*)"\r\n", io->stdOut); +#if MCUC1_CONFIG_CPU_IS_KINETIS + res = KIN1_UIDGet(&uid); + if (res==ERR_OK) { + res = KIN1_UIDtoString(&uid, buf, sizeof(buf)); + } + if (res!=ERR_OK) { + UTIL1_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR"); + } + CLS1_SendStatusStr((unsigned char*)" UID", buf, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); +#endif + CLS1_SendStatusStr((unsigned char*)" Family", (uint8_t*)KIN1_GetKinetisFamilyString(), io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + return ERR_OK; +} +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +static uint8_t PrintHelp(const CLS1_StdIOType *io) +{ + CLS1_SendHelpStr((unsigned char*)"KIN1", (unsigned char*)"Group of KIN1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" reset", (unsigned char*)"Performs a software reset\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut); + return ERR_OK; +} +#endif + +/* +** =================================================================== +** Method : SoftwareReset (component KinetisTools) +** +** Description : +** Performs a reset of the device +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SoftwareReset(void) +{ + /* Generic way to request a reset from software for ARM Cortex */ + /* See https://community.freescale.com/thread/99740 + To write to this register, you must write 0x5FA to the VECTKEY field, otherwise the processor ignores the write. + SYSRESETREQ will cause a system reset asynchronously, so need to wait afterwards. + */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M +#if MCUC1_CONFIG_PEX_SDK_USED + SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK; +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K + S32_SCB->AIRCR = S32_SCB_AIRCR_VECTKEY(0x5FA) | S32_SCB_AIRCR_SYSRESETREQ_MASK; +#else + SCB->AIRCR = (0x5FA<id[i] = 0; + } + if (sizeof(sim_uid_t)>sizeof(KIN1_UID)) { + return ERR_OVERFLOW; + } + /* copy into our own structure, data is right justified */ + for(i=0,j=sizeof(KIN1_UID)-sizeof(sim_uid_t);iid[j] = ((uint8_t*)&tmp)[i]; + } + #else /* not MCUC1_CONFIG_NXP_SDK_2_0_USED */ + #ifdef SIM_UIDMH /* 80 or 128 bit UUID: SIM_UIDMH, SIM_UIDML and SIM_UIDL */ + #ifdef SIM_UIDH + uid->id[0] = (SIM_UIDH>>24)&0xff; + uid->id[1] = (SIM_UIDH>>16)&0xff; + uid->id[2] = (SIM_UIDH>>8)&0xff; + uid->id[3] = SIM_UIDH&0xff; + #else + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + #endif + uid->id[4] = (SIM_UIDMH>>24)&0xff; + uid->id[5] = (SIM_UIDMH>>16)&0xff; + uid->id[6] = (SIM_UIDMH>>8)&0xff; + uid->id[7] = SIM_UIDMH&0xff; + + uid->id[8] = (SIM_UIDML>>24)&0xff; + uid->id[9] = (SIM_UIDML>>16)&0xff; + uid->id[10] = (SIM_UIDML>>8)&0xff; + uid->id[11] = SIM_UIDML&0xff; + + uid->id[12] = (SIM_UIDL>>24)&0xff; + uid->id[13] = (SIM_UIDL>>16)&0xff; + uid->id[14] = (SIM_UIDL>>8)&0xff; + uid->id[15] = SIM_UIDL&0xff; + #elif defined(SIM_UUIDMH) /* KE06Z: SIM_UUIDMH, SIM_UUIDML and SIM_UUIDL */ + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + uid->id[4] = 0; + uid->id[5] = 0; + uid->id[6] = (SIM_UUIDMH>>8)&0xff; + uid->id[7] = SIM_UUIDMH&0xff; + + uid->id[8] = (SIM_UUIDML>>24)&0xff; + uid->id[9] = (SIM_UUIDML>>16)&0xff; + uid->id[10] = (SIM_UUIDML>>8)&0xff; + uid->id[11] = SIM_UUIDML&0xff; + + uid->id[12] = (SIM_UUIDL>>24)&0xff; + uid->id[13] = (SIM_UUIDL>>16)&0xff; + uid->id[14] = (SIM_UUIDL>>8)&0xff; + uid->id[15] = SIM_UUIDL&0xff; + #else /* some devices like the KE02Z only have 64bit UUID: only SIM_UUIDH and SIM_UUIDL */ + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + uid->id[4] = 0; + uid->id[5] = 0; + uid->id[6] = 0; + uid->id[7] = 0; + uid->id[8] = (SIM_UUIDH>>24)&0xff; + uid->id[9] = (SIM_UUIDH>>16)&0xff; + uid->id[10] = (SIM_UUIDH>>8)&0xff; + uid->id[11] = SIM_UUIDH&0xff; + + uid->id[12] = (SIM_UUIDL>>24)&0xff; + uid->id[13] = (SIM_UUIDL>>16)&0xff; + uid->id[14] = (SIM_UUIDL>>8)&0xff; + uid->id[15] = SIM_UUIDL&0xff; + #endif + #endif /* MCUC1_CONFIG_NXP_SDK_2_0_USED */ + return ERR_OK; +#else + (void)uid; /* not used */ + return ERR_FAILED; +#endif +} + +/* +** =================================================================== +** Method : UIDSame (component KinetisTools) +** +** Description : +** Compares two UID +** Parameters : +** NAME - DESCRIPTION +** * src - Pointer to +** Variable_1 - +** Returns : +** --- - TRUE if the same, FALSE otherwise +** =================================================================== +*/ +/*! + * \brief Compares two UID + * \param src One UID + * \param dst The other UID + * \return TRUE if the two UID's are the same + */ +bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst) +{ + unsigned int i; + + for(i=0; iid[i]!=dst->id[i]) { + return FALSE; /* no match */ + } + } + return TRUE; +} + +/* +** =================================================================== +** Method : UIDtoString (component KinetisTools) +** +** Description : +** Returns the value of the UID as string +** Parameters : +** NAME - DESCRIPTION +** uid - +** * buf - Pointer to +** bufSize - +** Returns : +** --- - Error code +** =================================================================== +*/ +/*! + * \brief Transforms the 80bit UID into a string + * \param id Pointer to the buffer where to store the string + * \param bufSize Size of buffer in bytes + * \return Error code, ERR_OK if everything is ok. + */ +uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize) +{ + unsigned int i; + + UTIL1_strcpy(buf, bufSize, (unsigned char*)"{"); + for(i=0;iid[i]); + if (i>28)&0x3; /* bits 30..28 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM0FamilyStrings)/sizeof(KinetisM0FamilyStrings[0]))) { + return KinetisM0FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M0 Family ID out of bounds!"; + } + #elif defined(SIM_SRSID_FAMID) /* MKE02Z4 defines this, hopefully all other KE too... */ + return (KIN1_ConstCharPtr)"KE0x Family"; /* 0000 only KE0x supported */ + #elif defined(SIM_SDID_FAMID) + int32_t val; + + val = ((SIM->SDID)>>28)&0xF; /* bits 31..28 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM0FamilyStrings)/sizeof(KinetisM0FamilyStrings[0]))) { + return KinetisM0FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M0 Family ID out of bounds!"; + } + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif + #elif MCUC1_CONFIG_CORTEX_M==4 + #ifdef SIM_SDID /* normal Kinetis define this */ + int32_t val; + + val = (SIM_SDID>>4)&0x3; /* bits 6..4 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM4FamilyStrings)/sizeof(KinetisM4FamilyStrings[0]))) { + return KinetisM4FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M4 Family ID out of bounds!"; + } + #elif defined(SIM_SDID_FAMID) + int32_t val; + + val = ((SIM->SDID)>>4)&0x3; /* bits 6..4 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM4FamilyStrings)/sizeof(KinetisM4FamilyStrings[0]))) { + return KinetisM4FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M4 Family ID out of bounds!"; + } + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif + #elif MCUC1_CONFIG_CORTEX_M==7 + return (KIN1_ConstCharPtr)"Cortex-M7"; + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif +#elif MCUC1_CONFIG_CPU_IS_NORDIC_NRF + return (KIN1_ConstCharPtr)"Nordic nRF"; +#elif MCUC1_CONFIG_CPU_IS_STM + return (KIN1_ConstCharPtr)"STM32"; +#elif MCUC1_CONFIG_CPU_IS_IMXRT + return (KIN1_ConstCharPtr)"NXP i.MX RT"; +#elif MCUC1_CONFIG_CPU_IS_S32K + return (KIN1_ConstCharPtr)"NXP S32K"; +#elif MCUC1_CONFIG_CPU_IS_LPC55xx + return (KIN1_ConstCharPtr)"NXP LPC55xx"; +#elif MCUC1_CONFIG_CPU_IS_LPC + return (KIN1_ConstCharPtr)"NXP LPC"; +#else + return (KIN1_ConstCharPtr)"UNKNOWN"; +#endif +} + +/* +** =================================================================== +** Method : GetPC (component KinetisTools) +** +** Description : +** returns the program counter +** Parameters : None +** Returns : +** --- - program counter +** =================================================================== +*/ +void* KIN1_GetPC(void) +{ +#ifdef __GNUC__ + void *pc; + + __asm__ __volatile__ ("mov %0, pc" : "=r"(pc)); + return pc; +#else + #warning "only for GCC" + return NULL; +#endif +} + +/* +** =================================================================== +** Method : GetSP (component KinetisTools) +** +** Description : +** returns the stack pointer +** Parameters : None +** Returns : +** --- - stack pointer +** =================================================================== +*/ +void* KIN1_GetSP(void) +{ +#ifdef __GNUC__ + void *sp; + + __asm__ __volatile__ ("mrs %0, msp" : "=r"(sp)); + return sp; +#else + #warning "only for GCC" + return NULL; +#endif +} + +/* +** =================================================================== +** Method : SetPSP (component KinetisTools) +** +** Description : +** sets the process stack pointer +** Parameters : +** NAME - DESCRIPTION +** setval - new PSP value +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SetPSP(void *setval) +{ +#ifdef __GNUC__ + __asm__ volatile ("msr psp, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); + __asm__ volatile ("" ::: "memory"); +#else + #warning "only for GCC implemented" +#endif +} + +/* +** =================================================================== +** Method : SetLR (component KinetisTools) +** +** Description : +** Sets the link register +** Parameters : +** NAME - DESCRIPTION +** setval - new LR value +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SetLR(uint32_t setval) +{ +#ifdef __GNUC__ + __asm__ volatile ("mov lr, %[value]\n\t"::[value]"r"(setval):); + __asm__ volatile ("" ::: "memory"); +#else + #warning "only for GCC" +#endif +} + +/* +** =================================================================== +** Method : InitCycleCounter (component KinetisTools) +** +** Description : +** Initializes the cycle counter, available if the core has a +** DWT (Data Watchpoint and Trace) unit, usually present on +** M3/M4/M7 +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_InitCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : ResetCycleCounter (component KinetisTools) +** +** Description : +** Reset the cycle counter (set it to zero) +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_ResetCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : EnableCycleCounter (component KinetisTools) +** +** Description : +** Enables counting the cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_EnableCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : DisableCycleCounter (component KinetisTools) +** +** Description : +** Disables the cycle counter. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_DisableCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : GetCycleCounter (component KinetisTools) +** +** Description : +** Return the current cycle counter value +** Parameters : None +** Returns : +** --- - cycle counter +** =================================================================== +*/ +/** +uint32_t KIN1_GetCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : Deinit (component KinetisTools) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component KinetisTools) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_Init(void) +{ + /* Nothing needed */ +} + + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* END KIN1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.h new file mode 100644 index 0000000..314d83a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1.h @@ -0,0 +1,394 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KIN1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : KinetisTools +** Version : Component 01.041, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** +** Settings : +** Component name : KIN1 +** Utility : UTIL1 +** SDK : MCUC1 +** Shell : Enabled +** Shell : CLS1 +** Contents : +** SoftwareReset - void KIN1_SoftwareReset(void); +** UIDGet - uint8_t KIN1_UIDGet(KIN1_UID *uid); +** UIDSame - bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +** UIDtoString - uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +** GetKinetisFamilyString - KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +** GetPC - void* KIN1_GetPC(void); +** GetSP - void* KIN1_GetSP(void); +** SetPSP - void KIN1_SetPSP(void *setval); +** SetLR - void KIN1_SetLR(uint32_t setval); +** InitCycleCounter - void KIN1_InitCycleCounter(void); +** ResetCycleCounter - void KIN1_ResetCycleCounter(void); +** EnableCycleCounter - void KIN1_EnableCycleCounter(void); +** DisableCycleCounter - void KIN1_DisableCycleCounter(void); +** GetCycleCounter - uint32_t KIN1_GetCycleCounter(void); +** ParseCommand - uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const... +** Deinit - void KIN1_Deinit(void); +** Init - void KIN1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KIN1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KIN1_module KIN1 module documentation +** @{ +*/ + +#ifndef __KIN1_H +#define __KIN1_H + +/* MODULE KIN1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "KIN1config.h" /* configuration */ + +#include /* for size_t */ +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED + #include "CLS1.h" /* Command line shell */ +#endif + + +#ifndef __BWUserType_KIN1_ConstCharPtr +#define __BWUserType_KIN1_ConstCharPtr + typedef const uint8_t *KIN1_ConstCharPtr; /* Pointer to constant string */ +#endif + + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ + /* DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a DWT unit */ + #define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) + /*!< DWT Control register */ + #define KIN1_DWT_CYCCNTENA_BIT (1UL<<0) + /*!< CYCCNTENA bit in DWT_CONTROL register */ + #define KIN1_DWT_CYCCNT (*((volatile uint32_t*)0xE0001004)) + /*!< DWT Cycle Counter register */ + #define KIN1_DEMCR (*((volatile uint32_t*)0xE000EDFC)) + /*!< DEMCR: Debug Exception and Monitor Control Register */ + #define KIN1_TRCENA_BIT (1UL<<24) + /*!< Trace enable bit in DEMCR register */ +#endif + +typedef struct { + uint8_t id[16]; /* 128 bit ID */ +} KIN1_UID; + +typedef enum { + KIN1_FAMILY_K10_K12, /* K10 or K12 */ + KIN1_FAMILY_K20_K22, /* K10 or K12 */ + KIN1_FAMILY_K30_K11_K61, /* K30, K11 or K61 */ + KIN1_FAMILY_K40_K21, /* K40 or K21 */ + KIN1_FAMILY_K70, /* K70 */ + KIN1_FAMILY_UNKONWN, /* Unknown */ + KIN1_FAMILY_LAST /* Must be last one! */ +} KIN1_FAMILY; + +#define KIN1_PARSE_COMMAND_ENABLED KIN1_CONFIG_PARSE_COMMAND_ENABLED + /*!< set to 1 if method ParseCommand() is present, 0 otherwise */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const CLS1_StdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component KinetisTools) +** +** Description : +** Shell Command Line parser. Method is only available if Shell +** is enabled in the component properties. +** Parameters : +** NAME - DESCRIPTION +** cmd - Pointer to command string +** * handled - Pointer to variable which tells if +** the command has been handled or not +** * io - Pointer to I/O structure +** Returns : +** --- - Error code +** =================================================================== +*/ +#endif + +void KIN1_SoftwareReset(void); +/* +** =================================================================== +** Method : SoftwareReset (component KinetisTools) +** +** Description : +** Performs a reset of the device +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +uint8_t KIN1_UIDGet(KIN1_UID *uid); +/* +** =================================================================== +** Method : UIDGet (component KinetisTools) +** +** Description : +** Return the 128bit UID of the device +** Parameters : +** NAME - DESCRIPTION +** * uid - Pointer to +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +/* +** =================================================================== +** Method : UIDSame (component KinetisTools) +** +** Description : +** Compares two UID +** Parameters : +** NAME - DESCRIPTION +** * src - Pointer to +** Variable_1 - +** Returns : +** --- - TRUE if the same, FALSE otherwise +** =================================================================== +*/ + +uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : UIDtoString (component KinetisTools) +** +** Description : +** Returns the value of the UID as string +** Parameters : +** NAME - DESCRIPTION +** uid - +** * buf - Pointer to +** bufSize - +** Returns : +** --- - Error code +** =================================================================== +*/ + +KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +/* +** =================================================================== +** Method : GetKinetisFamilyString (component KinetisTools) +** +** Description : +** Determines the Kinetis Familiy based on SIM_SDID register +** Parameters : None +** Returns : +** --- - String describing the Kinetis Family +** =================================================================== +*/ + +void* KIN1_GetPC(void); +/* +** =================================================================== +** Method : GetPC (component KinetisTools) +** +** Description : +** returns the program counter +** Parameters : None +** Returns : +** --- - program counter +** =================================================================== +*/ + +void* KIN1_GetSP(void); +/* +** =================================================================== +** Method : GetSP (component KinetisTools) +** +** Description : +** returns the stack pointer +** Parameters : None +** Returns : +** --- - stack pointer +** =================================================================== +*/ + +void KIN1_SetPSP(void *setval); +/* +** =================================================================== +** Method : SetPSP (component KinetisTools) +** +** Description : +** sets the process stack pointer +** Parameters : +** NAME - DESCRIPTION +** setval - new PSP value +** Returns : Nothing +** =================================================================== +*/ + +void KIN1_SetLR(uint32_t setval); +/* +** =================================================================== +** Method : SetLR (component KinetisTools) +** +** Description : +** Sets the link register +** Parameters : +** NAME - DESCRIPTION +** setval - new LR value +** Returns : Nothing +** =================================================================== +*/ + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_InitCycleCounter() \ + KIN1_DEMCR |= KIN1_TRCENA_BIT + /*!< TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor Control Register */ +/* +** =================================================================== +** Method : InitCycleCounter (component KinetisTools) +** +** Description : +** Initializes the cycle counter, available if the core has a +** DWT (Data Watchpoint and Trace) unit, usually present on +** M3/M4/M7 +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_ResetCycleCounter() \ + KIN1_DWT_CYCCNT = 0 + /*!< Reset cycle counter */ +/* +** =================================================================== +** Method : ResetCycleCounter (component KinetisTools) +** +** Description : +** Reset the cycle counter (set it to zero) +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_EnableCycleCounter() \ + KIN1_DWT_CONTROL |= KIN1_DWT_CYCCNTENA_BIT + /*!< Enable cycle counter */ +/* +** =================================================================== +** Method : EnableCycleCounter (component KinetisTools) +** +** Description : +** Enables counting the cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_DisableCycleCounter() \ + KIN1_DWT_CONTROL &= ~KIN1_DWT_CYCCNTENA_BIT + /*!< Disable cycle counter */ +/* +** =================================================================== +** Method : DisableCycleCounter (component KinetisTools) +** +** Description : +** Disables the cycle counter. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_GetCycleCounter() \ + KIN1_DWT_CYCCNT + /*!< Read cycle counter register */ +/* +** =================================================================== +** Method : GetCycleCounter (component KinetisTools) +** +** Description : +** Return the current cycle counter value +** Parameters : None +** Returns : +** --- - cycle counter +** =================================================================== +*/ +#endif + +void KIN1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component KinetisTools) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void KIN1_Init(void); +/* +** =================================================================== +** Method : Init (component KinetisTools) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END KIN1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __KIN1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1config.h new file mode 100644 index 0000000..0c875a0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/KIN1config.h @@ -0,0 +1,29 @@ +/** + * \file + * \brief Configuration header file for Kinetis Tools (or ARM in general) + * + * This header file is used to configure settings of the Kinetis Tools module. + */ + +#ifndef __KIN1_CONFIG_H +#define __KIN1_CONFIG_H + +#if !defined(KIN1_CONFIG_PARSE_COMMAND_ENABLED) + #define KIN1_CONFIG_PARSE_COMMAND_ENABLED (1) + /*!< 1: shell support enabled, 0: otherwise */ +#endif + +#if MCUC1_CONFIG_NXP_SDK_2_0_USED + /* will include system header file in the implementation file */ +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3 + /* will include system header file in the implementation file */ +#elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* include here the low level CMSIS header files, e.g. with */ + #if MCUC1_CONFIG_CPU_IS_STM32 + #include "stm32f3xx_hal.h" /* header file for STM32F303K8 */ + #elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_NORDIC_NRF5 + #include "nrf.h" + #endif +#endif + +#endif /* __KIN1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.c new file mode 100644 index 0000000..643123c --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.c @@ -0,0 +1,226 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED1 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED1_On(void); +** Off - void LED1_Off(void); +** Neg - void LED1_Neg(void); +** Get - uint8_t LED1_Get(void); +** Put - void LED1_Put(uint8_t val); +** SetRatio16 - void LED1_SetRatio16(uint16_t ratio); +** Deinit - void LED1_Deinit(void); +** Init - void LED1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED1.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED1_module LED1 module documentation +** @{ +*/ + +/* MODULE LED1. */ + +#include "LED1.h" + +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_On(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Off(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Neg(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ +/* +uint8_t LED1_Get(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Put(uint8_t val) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED1_Init(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin1_Init(); +#endif + LED1_Off(); +} + +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED1_Deinit(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin1_Deinit(); +#endif +} + +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ +void LED1_SetRatio16(uint16_t ratio) +{ + /* on/off LED: binary on or off */ + if (ratio<(0xffff/2)) { + LED1_Off(); + } else { + LED1_On(); + } +} + +/* END LED1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.h new file mode 100644 index 0000000..72f170d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1.h @@ -0,0 +1,208 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED1 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED1_On(void); +** Off - void LED1_Off(void); +** Neg - void LED1_Neg(void); +** Get - uint8_t LED1_Get(void); +** Put - void LED1_Put(uint8_t val); +** SetRatio16 - void LED1_SetRatio16(uint16_t ratio); +** Deinit - void LED1_Deinit(void); +** Init - void LED1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED1.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED1_module LED1 module documentation +** @{ +*/ + +#ifndef __LED1_H +#define __LED1_H + +/* MODULE LED1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "LED1config.h" /* LED configuration */ +#include "LEDpin1.h" /* interface to pin */ + +#define LED1_ClrVal() LEDpin1_ClrVal() /* put the pin on low level */ +#define LED1_SetVal() LEDpin1_SetVal() /* put the pin on high level */ +#define LED1_SetInput() LEDpin1_SetInput() /* use the pin as input pin */ +#define LED1_SetOutput() LEDpin1_SetOutput() /* use the pin as output pin */ + +#define LED1_PARSE_COMMAND_ENABLED 0 /* set to 1 if method ParseCommand() is present, 0 otherwise */ + + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_On() LEDpin1_ClrVal() +#else + #define LED1_On() LEDpin1_SetVal() +#endif +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_Off() LEDpin1_SetVal() +#else + #define LED1_Off() LEDpin1_ClrVal() +#endif +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED1_Neg() LEDpin1_NegVal() +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_Get() (!(LEDpin1_GetVal())) +#else + #define LED1_Get() LEDpin1_GetVal() +#endif +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ + +void LED1_Init(void); +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED1_Put(val) ((val) ? LED1_On() : LED1_Off()) +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ + +void LED1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void LED1_SetRatio16(uint16_t ratio); +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ + +/* END LED1. */ + +#endif +/* ifndef __LED1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1config.h new file mode 100644 index 0000000..39e4975 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LED1config.h @@ -0,0 +1,14 @@ +#ifndef __LED1_CONFIG_H +#define __LED1_CONFIG_H + +#ifndef LED1_CONFIG_USE_GPIO_PIN + #define LED1_CONFIG_USE_GPIO_PIN (1) + /*!< 1: use GPIO pin; 0: use PWM pin */ +#endif + +#ifndef LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_CONFIG_IS_LOW_ACTIVE (1) + /*!< 1: LED is low active (cathode on port side), 0: LED is HIGH active (anode on port side) */ +#endif + +#endif /* __LED1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.c new file mode 100644 index 0000000..fcd0eed --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.c @@ -0,0 +1,171 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin1 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin1_GetVal(void); +** ClrVal - void LEDpin1_ClrVal(void); +** SetVal - void LEDpin1_SetVal(void); +** NegVal - void LEDpin1_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin1.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin1_module LEDpin1 module documentation +** @{ +*/ + +/* MODULE LEDpin1. */ + +#include "LEDpin1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : LEDpin1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool LEDpin1_GetVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_ClrVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_SetVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_NegVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* END LEDpin1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.h new file mode 100644 index 0000000..de25ab0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/LEDpin1.h @@ -0,0 +1,171 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin1 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin1_GetVal(void); +** ClrVal - void LEDpin1_ClrVal(void); +** SetVal - void LEDpin1_SetVal(void); +** NegVal - void LEDpin1_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin1.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin1_module LEDpin1 module documentation +** @{ +*/ + +#ifndef __LEDpin1_H +#define __LEDpin1_H + +/* MODULE LEDpin1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd1.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : LEDpin1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define LEDpin1_GetVal() (BitIoLdd1_GetVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_ClrVal() (BitIoLdd1_ClrVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_SetVal() (BitIoLdd1_SetVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_NegVal() (BitIoLdd1_NegVal(BitIoLdd1_DeviceData)) + +/* END LEDpin1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __LEDpin1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.c new file mode 100644 index 0000000..82d9257 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.c @@ -0,0 +1,95 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MCUC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : McuLibConfig +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** Configures the drivers for various SDKs and APIs used. +** Settings : +** Component name : MCUC1 +** SDK : Processor Expert +** Contents : +** Init - void MCUC1_Init(void); +** Deinit - void MCUC1_Deinit(void); +** +** * Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file MCUC1.h +** @version 01.00 +** @brief +** Configures the drivers for various SDKs and APIs used. +*/ +/*! +** @addtogroup MCUC1_module MCUC1 module documentation +** @{ +*/ + +/* MODULE MCUC1. */ + +#include "MCUC1.h" + +/* +** =================================================================== +** Method : Init (component McuLibConfig) +** +** Description : +** Driver initialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void MCUC1_Init(void) +{ + /* nothing to implement */ +} + +/* +** =================================================================== +** Method : Deinit (component McuLibConfig) +** +** Description : +** Driver deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void MCUC1_Deinit(void) +{ + /* nothing to implement */ +} + +/* END MCUC1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.h new file mode 100644 index 0000000..c275494 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1.h @@ -0,0 +1,195 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MCUC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : McuLibConfig +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** Configures the drivers for various SDKs and APIs used. +** Settings : +** Component name : MCUC1 +** SDK : Processor Expert +** Contents : +** Init - void MCUC1_Init(void); +** Deinit - void MCUC1_Deinit(void); +** +** * Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file MCUC1.h +** @version 01.00 +** @brief +** Configures the drivers for various SDKs and APIs used. +*/ +/*! +** @addtogroup MCUC1_module MCUC1 module documentation +** @{ +*/ + +#ifndef __MCUC1_H +#define __MCUC1_H + +/* MODULE MCUC1. */ +#include "MCUC1config.h" /* include configuration header file */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #ifndef __IASMARM__ /* not including standard header files if using IAR assembler */ + /* Include shared modules, which are used for whole project */ + #include "PE_Types.h" + #include "PE_Error.h" + #include "PE_Const.h" + #include "IO_Map.h" + #include "Cpu.h" /* include CPU related interfaces and defines */ + #endif +#else /* use non-Processor Expert SDK: generic or silicon vendor SDK */ + /* defines of common types used by Processor Expert, which might not be provided by the SDK */ + #if !(defined(__ICCARM__) || defined(__HIWARE__)) /* Hiware compiler (S08, S12) only supports C89 */ + #include /* uint8_t, int16_t, ... */ + #include /* bool, true, false, ... */ + #endif + + /* boolean values */ + #ifndef FALSE + #define FALSE 0x00u + #endif + #ifndef TRUE + #define TRUE 0x01u + #endif + + /* error codes */ + #define ERR_OK 0x00U /*!< OK */ + #define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ + #define ERR_RANGE 0x02U /*!< Parameter out of range. */ + #define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ + #define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ + #define ERR_MATH 0x05U /*!< Overflow during evaluation. */ + #define ERR_ENABLED 0x06U /*!< Device is enabled. */ + #define ERR_DISABLED 0x07U /*!< Device is disabled. */ + #define ERR_BUSY 0x08U /*!< Device is busy. */ + #define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ + #define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ + #define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ + #define ERR_BUSOFF 0x0CU /*!< Bus not available. */ + #define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ + #define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ + #define ERR_PARITY 0x0FU /*!< Parity error is detected. */ + #define ERR_NOISE 0x10U /*!< Noise error is detected. */ + #define ERR_IDLE 0x11U /*!< Idle error is detected. */ + #define ERR_FAULT 0x12U /*!< Fault error is detected. */ + #define ERR_BREAK 0x13U /*!< Break char is received during communication. */ + #define ERR_CRC 0x14U /*!< CRC error is detected. */ + #define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ + #define ERR_PROTECT 0x16U /*!< Protection error is detected. */ + #define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ + #define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ + #define ERR_COMMON 0x19U /*!< Common error of a device. */ + #define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ + #define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ + #define ERR_QFULL 0x1CU /*!< Queue is full. */ + #define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ + #define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ + #define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ + #define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ + #define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ + #define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ + #define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ + #define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ + #define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ + #define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ + #define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ + #define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ + #define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ + #define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ + #define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ + #define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ + #define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ + #define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ + #define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ + #define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ + #define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ + #define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ + #define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ + #define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ + #define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + + /* Other basic data types */ + typedef signed char int8; + typedef signed short int int16; + typedef signed long int int32; + + typedef unsigned char uint8; + typedef unsigned short int uint16; + typedef unsigned long int uint32; +#endif + + + + + +void MCUC1_Init(void); +/* +** =================================================================== +** Method : Init (component McuLibConfig) +** +** Description : +** Driver initialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void MCUC1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component McuLibConfig) +** +** Description : +** Driver deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END MCUC1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MCUC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1config.h new file mode 100644 index 0000000..1256db2 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/MCUC1config.h @@ -0,0 +1,162 @@ +/** + * \file + * \brief Configuration header file for McuLibConfig + * + * This header file is used to configure settings of the McuLibConfig module. + */ + +#ifndef __MCUC1_CONFIG_H +#define __MCUC1_CONFIG_H + +/* identification of CPU/core used. __CORTEX_M is defined in CMSIS-Core. + Otherwise CPU Family is set automatically by Processor Expert: detected: Kinetis (supported: "Kinetis", "S32K", "HCS08") +*/ +#ifndef MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M (1 || defined(__CORTEX_M)) + /*!< 1: ARM Cortex-M family, 0 otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_KINETIS + #define MCUC1_CONFIG_CPU_IS_KINETIS (1 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP Kinetis CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_S32K + #define MCUC1_CONFIG_CPU_IS_S32K (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP S32K CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC + #define MCUC1_CONFIG_CPU_IS_LPC (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP LPC CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC55xx + #define MCUC1_CONFIG_CPU_IS_LP55Cxx (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CPU_IS_LPC) + /*!< 1: NXP LPC55xx CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_CPU_IS_STM32 (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: STM32 ARM Cortex CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_IMXRT + #define MCUC1_CONFIG_CPU_IS_IMXRT (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP i.Mx RT CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_NORDIC_NRF + #define MCUC1_CONFIG_CPU_IS_NORDIC_NRF (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: Nordic nRF, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_HCS08 + #define MCUC1_CONFIG_CPU_IS_HCS08 (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: HCS08 CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V + #define MCUC1_CONFIG_CPU_IS_RISC_V (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: RISC-V CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY + #define MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY (1 && MCUC1_CONFIG_CPU_IS_RISC_V) + /*!< 1: VEGA Board: RISC-V RV32M1 RI5CY, 0: other core */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_ESP32 + #ifndef __XTENSA__ + #define __XTENSA__ 0 + #endif + #define MCUC1_CONFIG_CPU_IS_ESP32 (__XTENSA__) + /*!< 1: ESP32 CPU family, 0: otherwise. The ESP32 compiler defines __XTENSA__ with a value of 1 */ +#endif + + +/* identification of Cortex-M core. __FPU_USED can be defined in CMSIS-Core */ +#ifndef MCUC1_CONFIG_CORTEX_M + #define MCUC1_CONFIG_CORTEX_M (4) + /*!< 0: Cortex-M0, 3: M3, 4: M4, 7: M7, 33: M33, -1 otherwise */ +#endif +#if (1 && !defined(MCUC1_CONFIG_FPU_PRESENT) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_PRESENT) && (__FPU_PRESENT==1)) /* __FPU_PRESENT can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_PRESENT (1) +#else + #define MCUC1_CONFIG_FPU_PRESENT (0) +#endif + /*!< 1: floating point unit present, 0: otherwise */ +#if (1 && !defined(MCUC1_CONFIG_FPU_USED) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_USED) && (__FPU_USED==1)) /* __FPU_USED can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_USED (1) +#else + #define MCUC1_CONFIG_FPU_USED (0) +#endif + /*!< 1: using floating point unit, 0: otherwise */ + +/* macro for little and big endianess. ARM is little endian */ +#define MCUC1_CONFIG_CPU_IS_LITTLE_ENDIAN (MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + +/* Identifiers used to identify the SDK */ +#define MCUC1_CONFIG_SDK_GENERIC 0 + /*!< using a generic API/SDK */ +#define MCUC1_CONFIG_SDK_PROCESSOR_EXPERT 1 + /*!< using Processor Expert SDK */ +#define MCUC1_CONFIG_SDK_KINETIS_1_3 2 + /*!< using NXP Kinetis SDK V1.3 */ +#define MCUC1_CONFIG_SDK_KINETIS_2_0 3 + /*!< using NXP Kinetis SDK V2.0 */ +#define MCUC1_CONFIG_SDK_MCUXPRESSO_2_0 4 + /*!< using NXP MCUXpresso SDK V2.x, same as Kinetis SDK v2.0 */ +#define MCUC1_CONFIG_SDK_S32K 5 + /*!< SDK for S32K */ +#define MCUC1_CONFIG_SDK_NORDIC_NRF5 6 + /*!< Nordic nRF5 SDK */ + +#ifndef MCUC1_CONFIG_SDK_VERSION_MAJOR + #define MCUC1_CONFIG_SDK_VERSION_MAJOR (2) + /*!< SDK major version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_MINOR + #define MCUC1_CONFIG_SDK_VERSION_MINOR (5) + /*!< SDK minor version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_BUILD + #define MCUC1_CONFIG_SDK_VERSION_BUILD (0) + /*!< SDK build version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION + #define MCUC1_CONFIG_SDK_VERSION (MCUC1_CONFIG_SDK_VERSION_MAJOR*100)+(MCUC1_CONFIG_SDK_VERSION_MINOR*10)+MCUC1_CONFIG_SDK_VERSION_BUILD + /*!< Builds a single number with the SDK version (major, minor, build), e.g. 250 for 2.5.0 */ +#endif + +/* specify the SDK and API used */ +#ifndef MCUC1_CONFIG_SDK_VERSION_USED +#if MCUC1_CONFIG_CPU_IS_ESP32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For ESP32 we are using a generic SDK (actually the IDF one) */ +#elif MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For STM32 we are using a generic SDK (actually the CubeMX one) */ +#else + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + /*!< identify the version of SDK/API used */ +#endif +#endif + + +/* Configuration macro if FreeRTOS is used */ +#ifndef MCUC1_CONFIG_SDK_USE_FREERTOS + #define MCUC1_CONFIG_SDK_USE_FREERTOS (1) + /*!< 1: Use FreeRTOS; 0: no FreeRTOS used */ +#endif + +/* special macro to identify a set of SDKs used */ +#define MCUC1_CONFIG_NXP_SDK_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K) \ + ) + /*!< Using one of the Freescale/NXP SDKs */ + +#define MCUC1_CONFIG_NXP_SDK_2_0_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + ) + /*!< Using Freescale/NXP SDK V2.0 */ + +#define MCUC1_CONFIG_PEX_SDK_USED (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_PROCESSOR_EXPERT) + /*!< Using Processor Expert API */ + +#endif /* __MCUC1_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Const.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Const.h new file mode 100644 index 0000000..457bf48 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Const.h @@ -0,0 +1,95 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Const.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PE_Const +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "PE_Const" contains internal definitions +** of the constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Const.h +** @version 01.00 +** @brief +** This component "PE_Const" contains internal definitions +** of the constants. +*/ +/*! +** @addtogroup PE_Const_module PE_Const module documentation +** @{ +*/ + +#ifndef __PE_Const_H +#define __PE_Const_H + + +/* Reset cause constants */ +#define RSTSRC_WAKEUP 0x01U /*!< LLWU module wakeup reset */ +#define RSTSRC_LVD 0x02U /*!< Low-voltage detect reset */ +#define RSTSRC_LOC 0x04U /*!< Loss-of-clock reset */ +#define RSTSRC_LOL 0x08U /*!< Loss-of-lock reset */ +#define RSTSRC_COP 0x20U /*!< Watchdog reset */ +#define RSTSRC_WDOG 0x20U /*!< Watchdog reset */ +#define RSTSRC_PIN 0x40U /*!< External pin reset */ +#define RSTSRC_POR 0x80U /*!< Power-on reset */ +#define RSTSRC_JTAG 0x0100U /*!< JTAG reset pin */ +#define RSTSRC_LOCKUP 0x0200U /*!< Core Lock-up reset */ +#define RSTSRC_SW 0x0400U /*!< Software reset */ +#define RSTSRC_MDM_AP 0x0800U /*!< Reset caused by host debugger system */ +#define RSTSRC_EZPT 0x1000U /*!< EzPort reset */ +#define RSTSRC_SACKERR 0x2000U /*!< Stop Mode Acknowledge Error Reset */ + + +/* Low voltage interrupt cause constants */ +#define LVDSRC_LVD 0x01U /*!< Low voltage detect */ +#define LVDSRC_LVW 0x02U /*!< Low-voltage warning */ + +#endif /* _PE_Const_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Error.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Error.h new file mode 100644 index 0000000..c00cd96 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Error.h @@ -0,0 +1,128 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Error.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PE_Error +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component "PE_Error" contains internal definitions +** of the error constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Error.h +** @version 01.00 +** @brief +** This component "PE_Error" contains internal definitions +** of the error constants. +*/ +/*! +** @addtogroup PE_Error_module PE_Error module documentation +** @{ +*/ + +#ifndef __PE_Error_H +#define __PE_Error_H + +#define ERR_OK 0x00U /*!< OK */ +#define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ +#define ERR_RANGE 0x02U /*!< Parameter out of range. */ +#define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ +#define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ +#define ERR_MATH 0x05U /*!< Overflow during evaluation. */ +#define ERR_ENABLED 0x06U /*!< Device is enabled. */ +#define ERR_DISABLED 0x07U /*!< Device is disabled. */ +#define ERR_BUSY 0x08U /*!< Device is busy. */ +#define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ +#define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ +#define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ +#define ERR_BUSOFF 0x0CU /*!< Bus not available. */ +#define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ +#define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ +#define ERR_PARITY 0x0FU /*!< Parity error is detected. */ +#define ERR_NOISE 0x10U /*!< Noise error is detected. */ +#define ERR_IDLE 0x11U /*!< Idle error is detected. */ +#define ERR_FAULT 0x12U /*!< Fault error is detected. */ +#define ERR_BREAK 0x13U /*!< Break char is received during communication. */ +#define ERR_CRC 0x14U /*!< CRC error is detected. */ +#define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ +#define ERR_PROTECT 0x16U /*!< Protection error is detected. */ +#define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ +#define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ +#define ERR_COMMON 0x19U /*!< Common error of a device. */ +#define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ +#define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ +#define ERR_QFULL 0x1CU /*!< Queue is full. */ +#define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ +#define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ +#define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ +#define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ +#define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ +#define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ +#define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ +#define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ +#define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ +#define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ +#define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ +#define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ +#define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ +#define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ +#define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ +#define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ +#define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ +#define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ +#define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ +#define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ +#define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ +#define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ +#define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ +#define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ +#define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + +#endif /* __PE_Error_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.c new file mode 100644 index 0000000..d81d583 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.c @@ -0,0 +1,186 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.c +** @version 01.00 +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ + +/* MODULE PE_LDD. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +/* {FreeRTOS RTOS Adapter} No RTOS driver includes */ + +#include "PE_LDD.h" +#include "Cpu.h" + +/*lint -esym(765,PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory) Disable MISRA rule (8.10) checking for symbols (PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory). */ + +/* +** =========================================================================== +** Array of initialized device structures of LDD components. +** =========================================================================== +*/ +LDD_TDeviceData *PE_LDD_DeviceDataList[4] = { + NULL, + NULL, + NULL, + NULL + }; + +/* +** =========================================================================== +** The array of clock frequencies in configured clock configurations. +** =========================================================================== +*/ +/*! The array of clock configurations (frequencies) configured in configured clock configurations of the CPU component. */ +const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER] = { + /* Clock configuration 0 */ + { + CPU_CORE_CLK_HZ_CONFIG_0, /*!< Core clock frequency in clock configuration 0 */ + CPU_BUS_CLK_HZ_CONFIG_0, /*!< Bus clock frequency in clock configuration 0 */ + CPU_FLEXBUS_CLK_HZ_CONFIG_0, /*!< Flexbus clock frequency in clock configuration 0 */ + CPU_FLASH_CLK_HZ_CONFIG_0, /*!< FLASH clock frequency in clock configuration 0 */ + CPU_USB_CLK_HZ_CONFIG_0, /*!< USB clock frequency in clock configuration 0 */ + CPU_PLL_FLL_CLK_HZ_CONFIG_0, /*!< PLL/FLL clock frequency in clock configuration 0 */ + CPU_MCGIR_CLK_HZ_CONFIG_0, /*!< MCG internal reference clock frequency in clock configuration 0 */ + CPU_OSCER_CLK_HZ_CONFIG_0, /*!< System OSC external reference clock frequency in clock configuration 0 */ + CPU_ERCLK32K_CLK_HZ_CONFIG_0, /*!< External reference clock 32k frequency in clock configuration 0 */ + CPU_MCGFF_CLK_HZ_CONFIG_0 /*!< MCG fixed frequency clock */ + } +}; + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK22FN512LH12) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len) +{ + register uint8_t *ptr = (uint8_t*)SourceAddressPtr; + + if (len > 0U) { + while (len--) { + *ptr++ = c; + } + } +} + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK22FN512LH12) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress) +{ + bool result = FALSE; + + switch (PrphBaseAddress) { + /* Base address allocated by peripheral(s) FTM0 */ + case 0x40038000UL: + /* Base address allocated by peripheral(s) PTC */ + case 0x400FF080UL: + /* Base address allocated by peripheral(s) LPUART0 */ + case 0x4002A000UL: + /* Base address allocated by peripheral(s) UART0 */ + case 0x4006A000UL: + result = TRUE; + break; + default: + break; + } + return result; +} + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK22FN512LH12) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration) +{ + (void)ClockConfiguration; /*!< Parameter is not used, suppress unused argument warning */ + /* Just one clock configuration defined in CPU component. */ +} + +/* END PE_LDD. */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.h new file mode 100644 index 0000000..95b9a7c --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_LDD.h @@ -0,0 +1,152 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Version : Component 01.048, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:11, # CodeGen: 2 +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.h +** @version 01.00 +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ +#ifndef __PE_LDD_H +#define __PE_LDD_H + +/* MODULE PE_LDD. */ + +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "Pins1.h" +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "MCUC1.h" +#include "UTIL1.h" +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "WAIT1.h" +#include "RTT1.h" +#include "CLS1.h" +#include "XF1.h" +#include "CS1.h" +#include "KIN1.h" +#include "PTRC1.h" +#include "AS1.h" +#include "ASerialLdd1.h" +#include "USB1.h" +#include "CDC1.h" +#include "Tx1.h" +#include "Rx1.h" +#include "TMOUT1.h" +#include "AS2.h" +#include "ASerialLdd2.h" + + +/* +** =================================================================== +** Function prototypes +** =================================================================== +*/ + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK22FN512LH12) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK22FN512LH12) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress); + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK22FN512LH12) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration); + +/* END PE_LDD. */ + + +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Types.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Types.h new file mode 100644 index 0000000..e3af4e0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PE_Types.h @@ -0,0 +1,2577 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Types.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PE_Types +** Version : Driver 01.01 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Types.h +** @version 01.01 +** @brief +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +*/ +/*! +** @addtogroup PE_Types_module PE_Types module documentation +** @{ +*/ + +#ifndef __PE_Types_H +#define __PE_Types_H + +/* Standard ANSI C types */ +#include + +#ifndef FALSE + #define FALSE 0x00u /* Boolean value FALSE. FALSE is defined always as a zero value. */ +#endif +#ifndef TRUE + #define TRUE 0x01u /* Boolean value TRUE. TRUE is defined always as a non zero value. */ +#endif + +#ifndef NULL + #define NULL 0x00u +#endif + +/* PE types definition */ +#ifndef __cplusplus + #ifndef bool +typedef unsigned char bool; + #endif +#endif +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; +typedef unsigned long long dlong; +typedef unsigned char TPE_ErrCode; +#ifndef TPE_Float +typedef float TPE_Float; +#endif +#ifndef char_t +typedef char char_t; +#endif + +/* Other basic data types */ +typedef signed char int8; +typedef signed short int int16; +typedef signed long int int32; + +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned long int uint32; + + +/**********************************************************/ +/* Uniform multiplatform 8-bits peripheral access macros */ +/**********************************************************/ + +/* Enable maskable interrupts */ +#define __EI()\ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm("CPSIE f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + +/* Disable maskable interrupts */ +#define __DI() \ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm ("CPSID f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + + + +/* Save status register and disable interrupts */ +#define EnterCritical() \ + do {\ + uint8_t SR_reg_local;\ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "MRS R0, FAULTMASK\n\t" \ + "CPSID f\n\t" \ + "STRB R0, %[output]" \ + : [output] "=m" (SR_reg_local)\ + :: "r0");\ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + if (++SR_lock == 1u) {\ + SR_reg = SR_reg_local;\ + }\ + } while(0) + + +/* Restore status register */ +#define ExitCritical() \ + do {\ + if (--SR_lock == 0u) { \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "ldrb r0, %[input]\n\t"\ + "msr FAULTMASK,r0;\n\t" \ + ::[input] "m" (SR_reg) \ + : "r0"); \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + }\ + } while(0) + + +#define PE_DEBUGHALT() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "BKPT 255") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_NOP() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "NOP") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_WFI() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm("WFI") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + + +/* Interrupt definition template */ +#if !defined(PE_ISR) + #define PE_ISR(ISR_name) void __attribute__ ((interrupt)) ISR_name(void) +#endif + +/* Logical Device Drivers (LDD) types */ + +/*! Logical Device Driver API version */ +#define PE_LDD_VERSION 0x0100U + +/* LDD driver states */ +#define PE_LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION 0x01U /*!< LDD driver is disabled in the selected clock configuration */ +#define PE_LDD_DRIVER_DISABLED_BY_USER 0x02U /*!< LDD driver is disabled by the user */ +#define PE_LDD_DRIVER_BUSY 0x04U /*!< LDD driver is busy */ + +/*! Macro to register component device structure */ +#define PE_LDD_RegisterDeviceStructure(ComponentIndex, DeviceStructure) (PE_LDD_DeviceDataList[ComponentIndex] = DeviceStructure) + +/*! Macro to unregister component device structure */ +#define PE_LDD_UnregisterDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex] = NULL) + +/*! Macro to get the component device structure */ +#define PE_LDD_GetDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex]) + +/* +** =========================================================================== +** LDD component ID specifying the component instance in the project. This ID +** is used internally as an index to the array of LDD device structures. +** =========================================================================== +*/ +#define PE_LDD_COMPONENT_RTOSCNTRLDD1_ID 0x00U +#define PE_LDD_COMPONENT_BitIoLdd1_ID 0x01U +#define PE_LDD_COMPONENT_ASerialLdd1_ID 0x02U +#define PE_LDD_COMPONENT_ASerialLdd2_ID 0x03U + +/* +** =================================================================== +** Global HAL types and constants +** =================================================================== +*/ +typedef uint32_t LDD_TPinMask; /*!< Pin mask type. */ +typedef uint16_t LDD_TError; /*!< Error type. */ +typedef uint32_t LDD_TEventMask; /*!< Event mask type. */ +typedef uint8_t LDD_TClockConfiguration; /*!< CPU clock configuration type. */ +typedef void LDD_TDeviceData; /*!< Pointer to private device structure managed and used by HAL components. */ +typedef void* LDD_TDeviceDataPtr; /*!< Obsolete type for backward compatibility. */ +typedef void LDD_TData; /*!< General pointer to data. */ +typedef void LDD_TUserData; /*!< Pointer to this type specifies the user or RTOS specific data will be passed as an event or callback parameter. */ + +/*! Driver operation mode type. */ +typedef enum { + DOM_NONE, + DOM_RUN, + DOM_WAIT, + DOM_SLEEP, + DOM_STOP +} LDD_TDriverOperationMode; + +typedef uint16_t LDD_TDriverState; /*!< Driver state type. */ +typedef void LDD_TCallbackParam; /*!< Pointer to this type specifies the user data to be passed as a callback parameter. */ +typedef void (* LDD_TCallback)(LDD_TCallbackParam *CallbackParam); /*!< Callback type used for definition of callback functions. */ + +extern LDD_TDeviceData *PE_LDD_DeviceDataList[]; /*!< Array of LDD component device structures */ + + +/* Fills a memory area block by a specified value. Function defined in PE_LDD.c */ +extern void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + + +/* +** =================================================================== +** RTOS specific types and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} RTOS specific definition of type of Ioctl() command constants */ + + +/* +** =================================================================== +** Published RTOS settings and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} No published RTOS settings */ + + +/* +** =================================================================== +** TimerUnit device types and constants +** =================================================================== +*/ +#define LDD_TIMERUNIT_ON_CHANNEL_0 0x01u /*!< OnChannel0 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_1 0x02u /*!< OnChannel1 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_2 0x04u /*!< OnChannel2 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_3 0x08u /*!< OnChannel3 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_4 0x10u /*!< OnChannel4 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_5 0x20u /*!< OnChannel5 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_6 0x40u /*!< OnChannel6 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_7 0x80u /*!< OnChannel7 event mask value */ +#define LDD_TIMERUNIT_ON_COUNTER_RESTART 0x0100u /*!< OnCounterRestart event mask value */ + +/*! Direction of counting */ +typedef enum { + DIR_UP, /*!< UP */ + DIR_DOWN /*!< DOWN */ +} LDD_TimerUnit_TCounterDirection; + +/*! Output action type (flip-flop action on overrun or compare match) */ +typedef enum { + OUTPUT_NONE, /*!< NONE */ + OUTPUT_TOGGLE, /*!< TOGGLE */ + OUTPUT_CLEAR, /*!< CLEAR */ + OUTPUT_SET /*!< SET */ +} LDD_TimerUnit_TOutAction; + +/*! Input edge type */ +typedef enum { + EDGE_NONE, /*!< NONE */ + EDGE_RISING, /*!< RISING */ + EDGE_FALLING, /*!< FALLING */ + EDGE_BOTH /*!< BOTH */ +} LDD_TimerUnit_TEdge; + +typedef float LDD_TimerUnit_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** CMT device types and constants +** =================================================================== +*/ +#define LDD_CMT_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** PPG device types and constants +** =================================================================== +*/ +#define LDD_PPG_ON_END 0x01u /*!< OnEnd event mask value */ + +typedef float LDD_PPG_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** PWM types and constants +** =================================================================== +*/ +#define LDD_PWM_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** Capture types and constants +** =================================================================== +*/ +#define LDD_CAPTURE_ON_CAPTURE 0x01u /*!< OnCapture event mask value */ +#define LDD_CAPTURE_ON_OVERRUN 0x02u /*!< OnOverrun event mask value */ + +/* +** =================================================================== +** TimerInt types and constants +** =================================================================== +*/ +#define LDD_TIMERINT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** TimerOut types and constants +** =================================================================== +*/ +#define LDD_TIMEROUT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** EventCntr types and constants +** =================================================================== +*/ +#define LDD_EVENTCNTR_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** FreeCntr types and constants +** =================================================================== +*/ +#define LDD_FREECNTR_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** RealTime types and constants +** =================================================================== +*/ + +typedef float LDD_RealTime_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** TimeDate types and constants +** =================================================================== +*/ +#define LDD_TIMEDATE_ON_ALARM 0x01u /*!< OnAlarm event mask value */ +#define LDD_TIMEDATE_ON_SECOND 0x02u /*!< OnSecond event mask value */ + +/*!< Time struct */ +typedef struct { + uint16_t Hour; /*!< Hours (0 - 23) */ + uint16_t Min; /*!< Minutes (0 - 59) */ + uint16_t Sec; /*!< Seconds (0 - 59) */ + uint16_t Sec100; /*!< Hundredths of seconds (0 - 99) */ +} LDD_TimeDate_TTimeRec; + +/*!< Date struct */ +typedef struct { + uint16_t Year; /*!< Years (1998 - 2099) */ + uint16_t Month; /*!< Months (1 - 12) */ + uint16_t Day; /*!< Days (1 - 31) */ + uint16_t DayOfWeek; /*!< Day of week (0-Sunday, .. 6-Saturday) */ +} LDD_TimeDate_TDateRec; + +/* +** =================================================================== +** UART device types and constants +** =================================================================== +*/ +#define LDD_SERIAL_RX_PIN 0x01u /*!< Receiver pin mask */ +#define LDD_SERIAL_TX_PIN 0x02u /*!< Transmitter pin mask */ +#define LDD_SERIAL_CTS_PIN 0x04u /*!< CTS pin mask */ +#define LDD_SERIAL_RTS_PIN 0x08u /*!< RTS pin mask */ + +#define LDD_SERIAL_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SERIAL_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SERIAL_ON_BREAK 0x04u /*!< OnBreak event mask */ +#define LDD_SERIAL_ON_TXCOMPLETE 0x08u /*!< OnTxComplete event mask */ +#define LDD_SERIAL_ON_ERROR 0x10u /*!< OnError event mask */ + +#define LDD_SERIAL_RX_OVERRUN 0x01u /*!< Receiver overrun */ +#define LDD_SERIAL_PARITY_ERROR 0x02u /*!< Parity error */ +#define LDD_SERIAL_FRAMING_ERROR 0x04u /*!< Framing error */ +#define LDD_SERIAL_NOISE_ERROR 0x08u /*!< Noise error */ + +typedef uint32_t LDD_SERIAL_TError; /*!< Serial communication error type */ + +typedef uint8_t LDD_SERIAL_TDataWidth; /*!< Bit length type. The number of bits transmitted by one character. */ + +typedef uint16_t LDD_SERIAL_TSize; /*!< Type specifying the length of the data or buffer. */ + +typedef uint8_t LDD_SERIAL_TBaudMode; /*!< Type specifying the baud mode. */ + +/*! Type specifying the parity. */ +typedef enum { + LDD_SERIAL_PARITY_UNDEF, /*!< Undefined parity */ + LDD_SERIAL_PARITY_NONE, /*!< Parity none */ + LDD_SERIAL_PARITY_ODD, /*!< Parity odd */ + LDD_SERIAL_PARITY_EVEN, /*!< Parity even */ + LDD_SERIAL_PARITY_MARK, /*!< Parity mark */ + LDD_SERIAL_PARITY_SPACE /*!< Parity space */ +} LDD_SERIAL_TParity; + +/*! Type specifying the stop bit length. */ +typedef enum { + LDD_SERIAL_STOP_BIT_LEN_UNDEF, /*!< Undefined bit length */ + LDD_SERIAL_STOP_BIT_LEN_1, /*!< 1 bit length */ + LDD_SERIAL_STOP_BIT_LEN_1_5, /*!< 1.5 bit length */ + LDD_SERIAL_STOP_BIT_LEN_2 /*!< 2 bit length */ +} LDD_SERIAL_TStopBitLen; + +/*! Communication statistics */ +typedef struct { + uint32_t ReceivedChars; /*!< Number of received characters */ + uint32_t SentChars; /*!< Number of transmitted characters */ + uint32_t ReceivedBreaks; /*!< Number of received break characters */ + uint32_t ParityErrors; /*!< Number of receiver parity errors */ + uint32_t FramingErrors; /*!< Number of receiver framing errors */ + uint32_t OverrunErrors; /*!< Number of receiver overrun errors */ + uint32_t NoiseErrors; /*!< Number of receiver noise errors */ +} LDD_SERIAL_TStats; + +/*! Type specifying the loop mode operation. */ +typedef enum { + LOOPMODE_UNDEF, /*!< Undefined loop mode */ + LOOPMODE_NORMAL, /*!< Normal operation */ + LOOPMODE_AUTO_ECHO, /*!< Auto echo mode */ + LOOPMODE_LOCAL_LOOPBACK, /*!< Local loopback mode */ + LOOPMODE_REMOTE_LOOPBACK /*!< Remote loopback mode */ +} LDD_SERIAL_TLoopMode; + + +/* +** =================================================================== +** ADC device types and constants +** =================================================================== +*/ + +#define LDD_ADC_CHANNEL_0_PIN 0x01u /*!< Channel 0 pin mask */ +#define LDD_ADC_CHANNEL_1_PIN 0x02u /*!< Channel 1 pin mask */ +#define LDD_ADC_CHANNEL_2_PIN 0x04u /*!< Channel 2 pin mask */ +#define LDD_ADC_CHANNEL_3_PIN 0x08u /*!< Channel 3 pin mask */ +#define LDD_ADC_CHANNEL_4_PIN 0x10u /*!< Channel 4 pin mask */ +#define LDD_ADC_CHANNEL_5_PIN 0x20u /*!< Channel 5 pin mask */ +#define LDD_ADC_CHANNEL_6_PIN 0x40u /*!< Channel 6 pin mask */ +#define LDD_ADC_CHANNEL_7_PIN 0x80u /*!< Channel 7 pin mask */ +#define LDD_ADC_CHANNEL_8_PIN 0x0100u /*!< Channel 8 pin mask */ +#define LDD_ADC_CHANNEL_9_PIN 0x0200u /*!< Channel 9 pin mask */ +#define LDD_ADC_CHANNEL_10_PIN 0x0400u /*!< Channel 10 pin mask */ +#define LDD_ADC_CHANNEL_11_PIN 0x0800u /*!< Channel 11 pin mask */ +#define LDD_ADC_CHANNEL_12_PIN 0x1000u /*!< Channel 12 pin mask */ +#define LDD_ADC_CHANNEL_13_PIN 0x2000u /*!< Channel 13 pin mask */ +#define LDD_ADC_CHANNEL_14_PIN 0x4000u /*!< Channel 14 pin mask */ +#define LDD_ADC_CHANNEL_15_PIN 0x8000u /*!< Channel 15 pin mask */ +#define LDD_ADC_CHANNEL_16_PIN 0x00010000u /*!< Channel 16 pin mask */ +#define LDD_ADC_CHANNEL_17_PIN 0x00020000u /*!< Channel 17 pin mask */ +#define LDD_ADC_CHANNEL_18_PIN 0x00040000u /*!< Channel 18 pin mask */ +#define LDD_ADC_CHANNEL_19_PIN 0x00080000u /*!< Channel 19 pin mask */ +#define LDD_ADC_CHANNEL_20_PIN 0x00100000u /*!< Channel 20 pin mask */ +#define LDD_ADC_CHANNEL_21_PIN 0x00200000u /*!< Channel 21 pin mask */ +#define LDD_ADC_CHANNEL_22_PIN 0x00400000u /*!< Channel 22 pin mask */ +#define LDD_ADC_CHANNEL_23_PIN 0x00800000u /*!< Channel 23 pin mask */ +#define LDD_ADC_CHANNEL_24_PIN 0x01000000u /*!< Channel 24 pin mask */ +#define LDD_ADC_CHANNEL_25_PIN 0x02000000u /*!< Channel 25 pin mask */ +#define LDD_ADC_CHANNEL_26_PIN 0x04000000u /*!< Channel 26 pin mask */ +#define LDD_ADC_CHANNEL_27_PIN 0x08000000u /*!< Channel 27 pin mask */ +#define LDD_ADC_CHANNEL_28_PIN 0x10000000u /*!< Channel 28 pin mask */ +#define LDD_ADC_CHANNEL_29_PIN 0x20000000u /*!< Channel 29 pin mask */ +#define LDD_ADC_CHANNEL_30_PIN 0x40000000u /*!< Channel 30 pin mask */ +#define LDD_ADC_CHANNEL_31_PIN 0x80000000u /*!< Channel 31 pin mask */ +#define LDD_ADC_CHANNEL_32_PIN 0x01u /*!< Channel 32 pin mask */ +#define LDD_ADC_CHANNEL_33_PIN 0x02u /*!< Channel 33 pin mask */ +#define LDD_ADC_CHANNEL_34_PIN 0x04u /*!< Channel 34 pin mask */ +#define LDD_ADC_CHANNEL_35_PIN 0x08u /*!< Channel 35 pin mask */ +#define LDD_ADC_CHANNEL_36_PIN 0x10u /*!< Channel 36 pin mask */ +#define LDD_ADC_CHANNEL_37_PIN 0x20u /*!< Channel 37 pin mask */ +#define LDD_ADC_CHANNEL_38_PIN 0x40u /*!< Channel 38 pin mask */ +#define LDD_ADC_CHANNEL_39_PIN 0x80u /*!< Channel 39 pin mask */ +#define LDD_ADC_CHANNEL_40_PIN 0x0100u /*!< Channel 40 pin mask */ +#define LDD_ADC_CHANNEL_41_PIN 0x0200u /*!< Channel 41 pin mask */ +#define LDD_ADC_CHANNEL_42_PIN 0x0400u /*!< Channel 42 pin mask */ +#define LDD_ADC_CHANNEL_43_PIN 0x0800u /*!< Channel 43 pin mask */ +#define LDD_ADC_CHANNEL_44_PIN 0x1000u /*!< Channel 44 pin mask */ +#define LDD_ADC_CHANNEL_45_PIN 0x2000u /*!< Channel 45 pin mask */ +#define LDD_ADC_CHANNEL_46_PIN 0x4000u /*!< Channel 46 pin mask */ +#define LDD_ADC_CHANNEL_47_PIN 0x8000u /*!< Channel 47 pin mask */ +#define LDD_ADC_CHANNEL_48_PIN 0x00010000u /*!< Channel 48 pin mask */ +#define LDD_ADC_CHANNEL_49_PIN 0x00020000u /*!< Channel 49 pin mask */ +#define LDD_ADC_CHANNEL_50_PIN 0x00040000u /*!< Channel 50 pin mask */ +#define LDD_ADC_CHANNEL_51_PIN 0x00080000u /*!< Channel 51 pin mask */ +#define LDD_ADC_CHANNEL_52_PIN 0x00100000u /*!< Channel 52 pin mask */ +#define LDD_ADC_CHANNEL_53_PIN 0x00200000u /*!< Channel 53 pin mask */ +#define LDD_ADC_CHANNEL_54_PIN 0x00400000u /*!< Channel 54 pin mask */ +#define LDD_ADC_CHANNEL_55_PIN 0x00800000u /*!< Channel 55 pin mask */ +#define LDD_ADC_CHANNEL_56_PIN 0x01000000u /*!< Channel 56 pin mask */ +#define LDD_ADC_CHANNEL_57_PIN 0x02000000u /*!< Channel 57 pin mask */ +#define LDD_ADC_CHANNEL_58_PIN 0x04000000u /*!< Channel 58 pin mask */ +#define LDD_ADC_CHANNEL_59_PIN 0x08000000u /*!< Channel 59 pin mask */ +#define LDD_ADC_CHANNEL_60_PIN 0x10000000u /*!< Channel 60 pin mask */ +#define LDD_ADC_CHANNEL_61_PIN 0x20000000u /*!< Channel 61 pin mask */ +#define LDD_ADC_CHANNEL_62_PIN 0x40000000u /*!< Channel 62 pin mask */ +#define LDD_ADC_CHANNEL_63_PIN 0x80000000u /*!< Channel 63 pin mask */ + +#define LDD_ADC_TRIGGER_0_PIN 0x01u /*!< Trigger 0 pin mask */ +#define LDD_ADC_TRIGGER_1_PIN 0x02u /*!< Trigger 1 pin mask */ + +#define LDD_ADC_LOW_VOLT_REF_PIN 0x01u /*!< Low voltage reference pin mask */ +#define LDD_ADC_HIGH_VOLT_REF_PIN 0x02u /*!< High voltage reference pin mask */ + +#define LDD_ADC_ON_MEASUREMENT_COMPLETE 0x40u /*!< OnMeasurementComplete event mask */ +#define LDD_ADC_ON_ERROR 0x80u /*!< OnError event mask */ + +#define LDD_ADC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef uint32_t LDD_ADC_TErrorMask; /*!< ADC error type */ + +/*! Structure pins for pin connection method */ +typedef struct { + uint32_t Channel0_31PinMask; /*!< Channel pin mask for channels 0 through 31 */ + uint32_t Channel32_63PinMask; /*!< Channel pin mask for channels 32 through 63 */ + uint16_t TriggerPinMask; /*!< Trigger pin mask */ + uint8_t VoltRefPinMask; /*!< Voltage reference pin mask */ +} LDD_ADC_TPinMask; + +/*! Structure used to describing one sample */ +typedef struct { + uint8_t ChannelIdx; /*!< Channel index */ +} LDD_ADC_TSample; + +/*! Type specifying the ADC compare mode */ +typedef enum { + LDD_ADC_LESS_THAN = 0x00u, /*!< Compare true if the result is less than the Low compare value */ + LDD_ADC_GREATER_THAN_OR_EQUAL = 0x01u, /*!< Compare true if the result is greater than or equal to Low compare value */ + LDD_ADC_INSIDE_RANGE_INCLUSIVE = 0x02u, /*!< Compare true if the result is greater than or equal to Low compare value and the result is less than or equal to High compare value */ + LDD_ADC_INSIDE_RANGE_NOT_INCLUSIVE = 0x03u, /*!< Compare true if the result is greater than Low compare value and the result is less than High compare value */ + LDD_ADC_OUTSIDE_RANGE_INCLUSIVE = 0x04u, /*!< Compare true if the result is less than or equal to Low compare value or the result is greater than or equal to High compare value */ + LDD_ADC_OUTSIDE_RANGE_NOT_INCLUSIVE = 0x05u /*!< Compare true if the result is less than Low compare value or the result is greater than High compare value */ +} LDD_ADC_TCompareMode; + +/* +** =================================================================== +** I2C device types and constants +** =================================================================== +*/ + +#define LDD_I2C_SDA_PIN 0x01u /*!< SDA pin mask */ +#define LDD_I2C_SCL_PIN 0x02u /*!< SCL pin mask */ + +#define LDD_I2C_ON_MASTER_BLOCK_SENT 0x0001u /*!< OnMasterBlockSent event mask */ +#define LDD_I2C_ON_MASTER_BLOCK_RECEIVED 0x0002u /*!< OnMasterBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_SENT 0x0004u /*!< OnSlaveBlockSent event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_RECEIVED 0x0008u /*!< OnSlaveBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_TX_REQUEST 0x0010u /*!< OnSlaveTxRequest event mask */ +#define LDD_I2C_ON_SLAVE_RX_REQUEST 0x0020u /*!< OnSlaveRxRequest event mask */ +#define LDD_I2C_ON_ERROR 0x0040u /*!< OnError event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_CALL_ADDR 0x0080u /*!< OnSlaveSMBusCallAddr event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_ALERT_RESPONSE 0x0100u /*!< OnSlaveSMBusAlertResponse event mask */ +#define LDD_I2C_ON_SLAVE_GENERAL_CALL_ADDR 0x0200u /*!< OnSlaveGeneralCallAddr event mask */ +#define LDD_I2C_ON_MASTER_BYTE_RECEIVED 0x0400u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_SLAVE_BYTE_RECEIVED 0x0800u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_BUS_START_DETECTED 0x1000u /*!< OnBusStartDetected event mask */ +#define LDD_I2C_ON_BUS_STOP_DETECTED 0x2000u /*!< OnBusStopDetected event mask */ + +#define LDD_I2C_SLAVE_TX_UNDERRUN 0x0001u /*!< SlaveTxUnderrun error mask */ +#define LDD_I2C_SLAVE_RX_OVERRUN 0x0002u /*!< SlaveRxOverrun error mask */ +#define LDD_I2C_ARBIT_LOST 0x0004u /*!< ArbitLost error mask */ +#define LDD_I2C_MASTER_NACK 0x0008u /*!< MasterNACK error mask */ +#define LDD_I2C_SCL_LOW_TIMEOUT 0x0010u /*!< SCLLowTimeout error mask */ +#define LDD_I2C_SDA_LOW_TIMEOUT 0x0020u /*!< SDALowTimeout error mask */ +#define LDD_I2C_SLAVE_NACK 0x0040u /*!< SlaveNACK error mask */ + +typedef uint16_t LDD_I2C_TSize; /*!< Type specifying the length of the data or buffer. */ +typedef uint16_t LDD_I2C_TAddr; /*!< Type specifying the address variable */ +typedef uint16_t LDD_I2C_TErrorMask; /*!< Type specifying the error mask type. */ +typedef bool LDD_I2C_TMode; /*!< Type specifynng the Actual operating mode */ + +/*! Type specifying the address type */ +typedef enum { + LDD_I2C_ADDRTYPE_7BITS, /*!< 7 bits address */ + LDD_I2C_ADDRTYPE_10BITS, /*!< 10 bits address */ + LDD_I2C_ADDRTYPE_GENERAL_CALL /*!< General call address */ +} LDD_I2C_TAddrType; + +/*! Type specifying generate the stop condition */ +typedef enum { + LDD_I2C_NO_SEND_STOP, /*!< Do not send stop signal */ + LDD_I2C_SEND_STOP /*!< Send stop signal */ +} LDD_I2C_TSendStop; + +/*! Type specifying the I2C state of BUS. */ +typedef enum { + LDD_I2C_BUSY, /*!< The bus is busy */ + LDD_I2C_IDLE /*!< The bus is idle */ +} LDD_I2C_TBusState; + +/*! Type specifying the I2C byte acknowledge response. */ +typedef enum { + LDD_I2C_ACK_BYTE, /*!< Byte acknowledged */ + LDD_I2C_NACK_BYTE /*!< Byte not acknowledged */ +} LDD_I2C_TAckType; + +/*! Communication statistics */ +typedef struct { + uint32_t MasterSentChars; /*!< Number of master transmitted characters. */ + uint32_t MasterReceivedChars; /*!< Number of master received characters. */ + uint32_t MasterNacks; /*!< Number of no acknowledges. */ + uint32_t ArbitLost; /*!< Number of lost the bus arbitration. */ + uint32_t SlaveSentChars; /*!< Number of slave transmitted characters. */ + uint32_t SlaveReceivedChars; /*!< Number of slave received characters. */ + uint32_t SlaveTxUnderrun; /*!< Number of slave underrun. */ + uint32_t SlaveRxOverrun; /*!< Number of slave overrun. */ + uint32_t SlaveGeneralCallAddr; /*!< Number of a general call address. */ + uint32_t SlaveSmBusCallAddr; /*!< Number of a SMBus call address. */ + uint32_t SlaveSmBusAlertResponse; /*!< Number of slave SMBus alert response received. */ + uint32_t SCLLowTimeout; /*!< Number of SCL low timeout occur. */ + uint32_t SDALowTimeout; /*!< Number of SCL low timeout occur. */ +} LDD_I2C_TStats; + + +/* +** =================================================================== +** SegLCD device types and constants +** =================================================================== +*/ + +#define LDD_SEGLCD_ON_FRAME_FREQUENCY 0x0001u /*!< OnFrameFrequency event mask */ +#define LDD_SEGLCD_ON_FAULT_DETECT_COMPLETE 0x0002u /*!< OnFaultDetectComplete event mask */ + +typedef uint8_t LDD_SegLCD_TPinIndex; /*!< Type specifying the segment LCD pin index variable */ +typedef uint8_t LDD_SegLCD_TFrontplaneData; /*!< Type specifying the frontplane/backplane segment variable */ +typedef uint8_t LDD_SegLCD_TFaultValue; /*!< Type specifying the frontplane/backplane segment variable */ + +/*! Types specifying the segment LCD blinking. */ +typedef enum { + LDD_SEGLCD_BLINK_OFF, /*!< Disables display blinking */ + LDD_SEGLCD_BLINK_ALL, /*!< Display blank during the blink period */ + LDD_SEGLCD_BLINK_ALL_ALTERNATE /*!< Blinking between alternate backplane */ +} LDD_SegLCD_TBlinking; + +/*! Segment LCD blank state type. */ +typedef enum { + LDD_SEGLCD_BLANK_STATE, /*!< Blank display mode */ + LDD_SEGLCD_NORMAL_STATE, /*!< Normal display mode */ + LDD_SEGLCD_ALTERNATE_STATE /*!< Alternate display mode */ +} LDD_SegLCD_TSetBlank; + +/*! Segment LCD pin type (frontplane/backplane) */ +typedef enum { + LDD_SEGLCD_BACKPLANE_PIN, /*!< Backplane pin */ + LDD_SEGLCD_FRONTPLANE_PIN /*!< Frontplane pin */ +} LDD_SegLCD_TPinType; + + +/* +** =================================================================== +** GPIO device types and constants +** =================================================================== +*/ + +#define LDD_GPIO_PIN_0 0x01u /*!< Pin 0 inside the port */ +#define LDD_GPIO_PIN_1 0x02u /*!< Pin 1 inside the port */ +#define LDD_GPIO_PIN_2 0x04u /*!< Pin 2 inside the port */ +#define LDD_GPIO_PIN_3 0x08u /*!< Pin 3 inside the port */ +#define LDD_GPIO_PIN_4 0x10u /*!< Pin 4 inside the port */ +#define LDD_GPIO_PIN_5 0x20u /*!< Pin 5 inside the port */ +#define LDD_GPIO_PIN_6 0x40u /*!< Pin 6 inside the port */ +#define LDD_GPIO_PIN_7 0x80u /*!< Pin 7 inside the port */ +#define LDD_GPIO_PIN_8 0x0100u /*!< Pin 8 inside the port */ +#define LDD_GPIO_PIN_9 0x0200u /*!< Pin 9 inside the port */ +#define LDD_GPIO_PIN_10 0x0400u /*!< Pin 10 inside the port */ +#define LDD_GPIO_PIN_11 0x0800u /*!< Pin 11 inside the port */ +#define LDD_GPIO_PIN_12 0x1000u /*!< Pin 12 inside the port */ +#define LDD_GPIO_PIN_13 0x2000u /*!< Pin 13 inside the port */ +#define LDD_GPIO_PIN_14 0x4000u /*!< Pin 14 inside the port */ +#define LDD_GPIO_PIN_15 0x8000u /*!< Pin 15 inside the port */ +#define LDD_GPIO_PIN_16 0x00010000u /*!< Pin 16 inside the port */ +#define LDD_GPIO_PIN_17 0x00020000u /*!< Pin 17 inside the port */ +#define LDD_GPIO_PIN_18 0x00040000u /*!< Pin 18 inside the port */ +#define LDD_GPIO_PIN_19 0x00080000u /*!< Pin 19 inside the port */ +#define LDD_GPIO_PIN_20 0x00100000u /*!< Pin 20 inside the port */ +#define LDD_GPIO_PIN_21 0x00200000u /*!< Pin 21 inside the port */ +#define LDD_GPIO_PIN_22 0x00400000u /*!< Pin 22 inside the port */ +#define LDD_GPIO_PIN_23 0x00800000u /*!< Pin 23 inside the port */ +#define LDD_GPIO_PIN_24 0x01000000u /*!< Pin 24 inside the port */ +#define LDD_GPIO_PIN_25 0x02000000u /*!< Pin 25 inside the port */ +#define LDD_GPIO_PIN_26 0x04000000u /*!< Pin 26 inside the port */ +#define LDD_GPIO_PIN_27 0x08000000u /*!< Pin 27 inside the port */ +#define LDD_GPIO_PIN_28 0x10000000u /*!< Pin 28 inside the port */ +#define LDD_GPIO_PIN_29 0x20000000u /*!< Pin 29 inside the port */ +#define LDD_GPIO_PIN_30 0x40000000u /*!< Pin 30 inside the port */ +#define LDD_GPIO_PIN_31 0x80000000u /*!< Pin 31 inside the port */ + +#define LDD_GPIO_ON_PORT_EVENT 0x01u /*!< OnPortEvent event mask */ + +typedef uint32_t LDD_GPIO_TBitField; /*!< Abstract type specifying the bit field within the port. */ + +/*! Defines condition when event is invoked. */ +typedef enum { + LDD_GPIO_DISABLED = 0x00u, /*!< Event doesn't invoke */ + LDD_GPIO_LOW = 0x00080000u, /*!< Event when logic zero */ + LDD_GPIO_HIGH = 0x000C0000u, /*!< Event when logic one */ + LDD_GPIO_RISING = 0x00090000u, /*!< Event on rising edge */ + LDD_GPIO_FALLING = 0x000A0000u, /*!< Event on falling edge */ + LDD_GPIO_BOTH = 0x000B0000u /*!< Event on rising and falling edge */ +} LDD_GPIO_TEventCondition; /*!< Defines condition when event is invoked. */ + +#define LDD_GPIO_EVENT_CONDITIONS_MASK 0x000F0000u + +/* +** =================================================================== +** BITSIO device types and constants +** =================================================================== +*/ +#define LDD_BITSIO_PIN_0 0x01U /*!< Pin 0 inside pin list of component */ +#define LDD_BITSIO_PIN_1 0x02U /*!< Pin 1 inside pin list of component */ +#define LDD_BITSIO_PIN_2 0x04U /*!< Pin 2 inside pin list of component */ +#define LDD_BITSIO_PIN_3 0x08U /*!< Pin 3 inside pin list of component */ +#define LDD_BITSIO_PIN_4 0x10U /*!< Pin 4 inside pin list of component */ +#define LDD_BITSIO_PIN_5 0x20U /*!< Pin 5 inside pin list of component */ +#define LDD_BITSIO_PIN_6 0x40U /*!< Pin 6 inside pin list of component */ +#define LDD_BITSIO_PIN_7 0x80U /*!< Pin 7 inside pin list of component */ +#define LDD_BITSIO_PIN_8 0x0100U /*!< Pin 8 inside pin list of component */ +#define LDD_BITSIO_PIN_9 0x0200U /*!< Pin 9 inside pin list of component */ +#define LDD_BITSIO_PIN_10 0x0400U /*!< Pin 10 inside pin list of component */ +#define LDD_BITSIO_PIN_11 0x0800U /*!< Pin 11 inside pin list of component */ +#define LDD_BITSIO_PIN_12 0x1000U /*!< Pin 12 inside pin list of component */ +#define LDD_BITSIO_PIN_13 0x2000U /*!< Pin 13 inside pin list of component */ +#define LDD_BITSIO_PIN_14 0x4000U /*!< Pin 14 inside pin list of component */ +#define LDD_BITSIO_PIN_15 0x8000U /*!< Pin 15 inside pin list of component */ +#define LDD_BITSIO_PIN_16 0x00010000U /*!< Pin 16 inside pin list of component */ +#define LDD_BITSIO_PIN_17 0x00020000U /*!< Pin 17 inside pin list of component */ +#define LDD_BITSIO_PIN_18 0x00040000U /*!< Pin 18 inside pin list of component */ +#define LDD_BITSIO_PIN_19 0x00080000U /*!< Pin 19 inside pin list of component */ +#define LDD_BITSIO_PIN_20 0x00100000U /*!< Pin 20 inside pin list of component */ +#define LDD_BITSIO_PIN_21 0x00200000U /*!< Pin 21 inside pin list of component */ +#define LDD_BITSIO_PIN_22 0x00400000U /*!< Pin 22 inside pin list of component */ +#define LDD_BITSIO_PIN_23 0x00800000U /*!< Pin 23 inside pin list of component */ +#define LDD_BITSIO_PIN_24 0x01000000U /*!< Pin 24 inside pin list of component */ +#define LDD_BITSIO_PIN_25 0x02000000U /*!< Pin 25 inside pin list of component */ +#define LDD_BITSIO_PIN_26 0x04000000U /*!< Pin 26 inside pin list of component */ +#define LDD_BITSIO_PIN_27 0x08000000U /*!< Pin 27 inside pin list of component */ +#define LDD_BITSIO_PIN_28 0x10000000U /*!< Pin 28 inside pin list of component */ +#define LDD_BITSIO_PIN_29 0x20000000U /*!< Pin 29 inside pin list of component */ +#define LDD_BITSIO_PIN_30 0x40000000U /*!< Pin 30 inside pin list of component */ +#define LDD_BITSIO_PIN_31 0x80000000U /*!< Pin 31 inside pin list of component */ + +/* +** =================================================================== +** Ethernet device types and constants +** =================================================================== +*/ + +#define LDD_ETH_MDC_PIN 0x01u /*!< MDC pin mask */ +#define LDD_ETH_MDIO_PIN 0x02u /*!< MDIO pin mask */ +#define LDD_ETH_COL_PIN 0x04u /*!< COL pin mask */ +#define LDD_ETH_CRS_PIN 0x08u /*!< CRS pin mask */ +#define LDD_ETH_TXCLK_PIN 0x10u /*!< TXCLK pin mask */ +#define LDD_ETH_TXD0_PIN 0x20u /*!< TXD0 pin mask */ +#define LDD_ETH_TXD1_PIN 0x40u /*!< TXD1 pin mask */ +#define LDD_ETH_TXD2_PIN 0x80u /*!< TXD2 pin mask */ +#define LDD_ETH_TXD3_PIN 0x0100u /*!< TXD3 pin mask */ +#define LDD_ETH_TXEN_PIN 0x0200u /*!< TXEN pin mask */ +#define LDD_ETH_TXER_PIN 0x0400u /*!< TXER pin mask */ +#define LDD_ETH_RXCLK_PIN 0x0800u /*!< RXCLK pin mask */ +#define LDD_ETH_RXDV_PIN 0x1000u /*!< RXDV pin mask */ +#define LDD_ETH_RXD0_PIN 0x2000u /*!< RXD0 pin mask */ +#define LDD_ETH_RXD1_PIN 0x4000u /*!< RXD1 pin mask */ +#define LDD_ETH_RXD2_PIN 0x8000u /*!< RXD2 pin mask */ +#define LDD_ETH_RXD3_PIN 0x00010000u /*!< RXD3 pin mask */ +#define LDD_ETH_RXER_PIN 0x00020000u /*!< RXER pin mask */ + +#define LDD_ETH_ON_FRAME_TRANSMITTED 0x01u /*!< OnFrameTransmitted event mask */ +#define LDD_ETH_ON_FRAME_TRANSMITTED_TIMESTAMPED 0x02u /*!< OnFrameTransmittedTimestamped event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED 0x04u /*!< OnFrameReceived event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED_TIMESTAMPED 0x08u /*!< OnFrameReceivedTimestamped event mask */ +#define LDD_ETH_ON_MII_FINISHED 0x10u /*!< OnMIIFinished event mask */ +#define LDD_ETH_ON_FATAL_ERROR 0x20u /*!< OnFatalError event mask */ +#define LDD_ETH_ON_WAKE_UP 0x40u /*!< OnWakeUp event mask */ + +typedef uint8_t LDD_ETH_TMACAddress[6]; /*!< Ethernet MAC address */ + +/*! Ethernet duplex mode */ +typedef enum { + LDD_ETH_FULL_DUPLEX, /*!< Full duplex mode */ + LDD_ETH_HALF_DUPLEX /*!< Half duplex mode */ +} LDD_ETH_TDuplexMode; + +/*! Ethernet address filter mode options */ +typedef enum { + LDD_ETH_PROMISC, /*!< Promiscuous mode */ + LDD_ETH_REJECT_BC, /*!< Reject broadcast frames */ + LDD_ETH_ACCEPT_BC /*!< Accept broadcast frames */ +} LDD_ETH_TFilterMode; + +/*! Ethernet sleep mode options */ +typedef enum { + LDD_ETH_ENABLED, /*!< Sleep mode enabled */ + LDD_ETH_ENABLED_WITH_WAKEUP, /*!< Sleep mode enabled, waiting for wake-up */ + LDD_ETH_DISABLED /*!< Sleep mode disabled */ +} LDD_ETH_TSleepMode; + +/*! Ethernet frame buffer (fragment) descriptor */ +typedef struct { + uint8_t *DataPtr; /*!< Pointer to buffer data */ + uint16_t Size; /*!< Buffer data size */ +} LDD_ETH_TBufferDesc; + +typedef LDD_ETH_TBufferDesc* LDD_ETH_TBufferDescPtr; /*!< Frame buffer descriptor pointer type */ + +/*! Ethernet communication statistics */ +typedef struct { + uint32_t TxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t TxRMONOctets; /*!< Octet count for frames transmitted without error */ + uint32_t TxRMONPackets; /*!< Transmitted packet count */ + uint32_t TxRMONBroadcastPackets; /*!< Transmitted broadcast packets */ + uint32_t TxRMONMulticastPackets; /*!< Transmitted multicast packets */ + uint32_t TxRMONCRCAlignErrors; /*!< Transmitted packets with CRC or alignment error */ + uint32_t TxRMONUndersizePackets; /*!< Transmitted packets smaller than 64 bytes with good CRC */ + uint32_t TxRMONOversizePackets; /*!< Transmitted packets greater than max. frame length with good CRC */ + uint32_t TxRMONFragments; /*!< Transmitted packets smaller than 64 bytes with bad CRC */ + uint32_t TxRMONJabbers; /*!< Transmitted packets greater than max. frame length with bad CRC */ + uint32_t TxRMONCollisions; /*!< Transmit collision count */ + uint32_t TxRMONPackets64Octets; /*!< Transmitted 64 byte packets */ + uint32_t TxRMONPackets65To127Octets; /*!< Transmitted 65 to 127 byte packets */ + uint32_t TxRMONPackets128To255Octets; /*!< Transmitted 128 to 255 byte packets */ + uint32_t TxRMONPackets256To511Octets; /*!< Transmitted 256 to 511 byte packets */ + uint32_t TxRMONPackets512To1023Octets; /*!< Transmitted 512 to 1023 byte packets */ + uint32_t TxRMONPackets1024To2047Octets; /*!< Transmitted 1024 to 2047 byte packets */ + uint32_t TxRMONPacketsGreaterThan2048Octets; /*!< Transmitted packets greater than 2048 byte */ + uint32_t TxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t TxIEEEFrameOK; /*!< Frames transmitted OK */ + uint32_t TxIEEESingleCollision; /*!< Frames transmitted with single collision */ + uint32_t TxIEEEMultipleCollisions; /*!< Frames transmitted with multiple collisions */ + uint32_t TxIEEEDeferralDelay; /*!< Frames transmitted after deferral delay */ + uint32_t TxIEEELateCollision; /*!< Frames transmitted with late collision */ + uint32_t TxIEEEExcessiveCollision; /*!< Frames transmitted with excessive collisions */ + uint32_t TxIEEEFIFOUnderrun; /*!< Frames transmitted with transmit FIFO underrun */ + uint32_t TxIEEECarrierSenseError; /*!< Frames transmitted with carrier sense error */ + uint32_t TxIEEESQEError; /*!< Frames transmitted with SQE error */ + uint32_t TxIEEEPauseFrame; /*!< Flow control pause frames transmitted */ + uint32_t TxIEEEOctetsOK; /*!< Octet count for frames transmitted without error */ + uint32_t RxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t RxRMONOctets; /*!< Octet count for frames recieved without error */ + uint32_t RxRMONPackets; /*!< Received packet count */ + uint32_t RxRMONBroadcastPackets; /*!< Received broadcast packets */ + uint32_t RxRMONMulticastPackets; /*!< Received multicast packets */ + uint32_t RxRMONCRCAlignErrors; /*!< Received packets with CRC or alignment error */ + uint32_t RxRMONUndersizePackets; /*!< Received packets smaller than 64 bytes with good CRC */ + uint32_t RxRMONOversizePackets; /*!< Received packets greater than max. frame length with good CRC */ + uint32_t RxRMONFragments; /*!< Received packets smaller than 64 bytes with bad CRC */ + uint32_t RxRMONJabbers; /*!< Received packets greater than max. frame length with bad CRC */ + uint32_t RxRMONPackets64Octets; /*!< Received 64 byte packets */ + uint32_t RxRMONPackets65To127Octets; /*!< Received 65 to 127 byte packets */ + uint32_t RxRMONPackets128To255Octets; /*!< Received 128 to 255 byte packets */ + uint32_t RxRMONPackets256To511Octets; /*!< Received 256 to 511 byte packets */ + uint32_t RxRMONPackets512To1023Octets; /*!< Received 512 to 1023 byte packets */ + uint32_t RxRMONPackets1024To2047Octets; /*!< Received 1024 to 2047 byte packets */ + uint32_t RxRMONPacketsGreaterThan2048Octets; /*!< Received packets greater than 2048 byte */ + uint32_t RxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t RxIEEEFrameOK; /*!< Frames received OK */ + uint32_t RxIEEECRCError; /*!< Frames received with CRC error */ + uint32_t RxIEEEAlignmentError; /*!< Frames received with alignment error */ + uint32_t RxIEEEFIFOOverflow; /*!< Receive FIFO overflow count */ + uint32_t RxIEEEPauseFrame; /*!< Flow control pause frames received */ + uint32_t RxIEEEOctetsOK; /*!< Octet count for frames received without error */ +} LDD_ETH_TStats; + +/* +** =================================================================== +** FlexCAN device types and constants +** =================================================================== +*/ + +typedef uint8_t LDD_CAN_TMBIndex; /*!< CAN message buffer index */ +typedef uint32_t LDD_CAN_TAccMask; /*!< Type specifying the acceptance mask variable. */ +typedef uint32_t LDD_CAN_TMessageID; /*!< Type specifying the ID mask variable. */ +typedef uint8_t LDD_CAN_TErrorCounter; /*!< Type specifying the error counter variable. */ +typedef uint32_t LDD_CAN_TErrorMask; /*!< Type specifying the error mask variable. */ +typedef uint16_t LDD_CAN_TBufferMask; /*!< Type specifying the message buffer mask variable. */ +#define LDD_CAN_RX_PIN 0x01U /*!< Rx pin mask */ +#define LDD_CAN_TX_PIN 0x02U /*!< Tx pin mask */ + +#define LDD_CAN_ON_FULL_RXBUFFER 0x01U /*!< OnFullRxBuffer event mask */ +#define LDD_CAN_ON_FREE_TXBUFFER 0x02U /*!< OnFreeTxBuffer event mask */ +#define LDD_CAN_ON_BUSOFF 0x04U /*!< OnBusOff event mask */ +#define LDD_CAN_ON_TXWARNING 0x08U /*!< OnTransmitterWarning event mask */ +#define LDD_CAN_ON_RXWARNING 0x10U /*!< OnReceiverWarning event mask */ +#define LDD_CAN_ON_ERROR 0x20U /*!< OnError event mask */ +#define LDD_CAN_ON_WAKEUP 0x40U /*!< OnWakeUp event mask */ + +#define LDD_CAN_BIT0_ERROR 0x4000UL /*!< Bit0 error detect error mask */ +#define LDD_CAN_BIT1_ERROR 0x8000UL /*!< Bit1 error detect error mask */ +#define LDD_CAN_ACK_ERROR 0x2000UL /*!< Acknowledge error detect error mask */ +#define LDD_CAN_CRC_ERROR 0x1000UL /*!< Cyclic redundancy check error detect error mask */ +#define LDD_CAN_FORM_ERROR 0x0800UL /*!< Message form error detect error mask */ +#define LDD_CAN_STUFFING_ERROR 0x0400UL /*!< Bit stuff error detect error mask */ + +#define LDD_CAN_MESSAGE_ID_EXT 0x80000000UL /*!< Value specifying extended Mask, ID */ + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_MB_RX_NOT_ACTIVE = 0x00U, + LDD_CAN_MB_RX_FULL = 0x02U, + LDD_CAN_MB_RX_EMPTY = 0x04U, + LDD_CAN_MB_RX_OVERRUN = 0x06U, + LDD_CAN_MB_RX_BUSY = 0x01U, + LDD_CAN_MB_RX_RANSWER = 0x0AU +} LDD_CAN_TRxBufferState; + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_DATA_FRAME, /*!< Data frame type received or transmitted */ + LDD_CAN_REMOTE_FRAME, /*!< Remote frame type */ + LDD_CAN_RESPONSE_FRAME /*!< Response frame type - Tx buffer send data after receiving remote frame with the same ID */ +} LDD_CAN_TFrameType; + +/*! Type specifying the CAN communication statistics. */ +typedef struct { + uint32_t TxFrames; /*!< Transmitted frame counter */ + uint32_t TxWarnings; /*!< Transmission warning counter */ + uint32_t RxFrames; /*!< Received frame counter */ + uint32_t RxWarnings; /*!< Reception warning counter */ + uint32_t BusOffs; /*!< Bus off counter */ + uint32_t Wakeups; /*!< Wakeup counter */ + uint32_t Bit0Errors; /*!< Bit0 error counter */ + uint32_t Bit1Errors; /*!< Bit1 error counter */ + uint32_t AckErrors; /*!< ACK error counter */ + uint32_t CrcErrors; /*!< CRC error counter */ + uint32_t FormErrors; /*!< Message form error counter */ + uint32_t BitStuffErrors; /*!< Bit stuff error counter */ + uint32_t Errors; /*!< Error counter */ +} LDD_CAN_TStats; + +/*! Type specifying the CAN frame features. */ +typedef struct { + LDD_CAN_TMessageID MessageID; /*!< Message ID */ + LDD_CAN_TFrameType FrameType; /*!< Type of the frame DATA/REMOTE */ + uint8_t *Data; /*!< Message data buffer */ + uint8_t Length; /*!< Message length */ + uint16_t TimeStamp; /*!< Message time stamp */ + uint8_t LocPriority; /*!< Local Priority Tx Buffers */ +} LDD_CAN_TFrame; + +/* +** =================================================================== +** USB device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_USB_ON_DEVICE_RESET 0x00000001u /*!< OnDeviceReset event mask */ +#define LDD_USB_ON_DEVICE_SPEED_DETECT 0x00000002u /*!< OnDeviceSpeedDetect event mask */ +#define LDD_USB_ON_DEVICE_SUSPEND 0x00000004u /*!< OnDeviceSuspend event mask */ +#define LDD_USB_ON_DEVICE_RESUME 0x00000008u /*!< OnDeviceResume event mask */ +#define LDD_USB_ON_DEVICE_SETUP_PACKET 0x00000010u /*!< OnDeviceSetupPacket event mask */ +#define LDD_USB_ON_DEVICE_SOF 0x00000020u /*!< OnDeviceSof event mask */ +#define LDD_USB_ON_DEVICE_1MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_1_MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_ERROR 0x00000080u /*!< OnDeviceError event mask */ +#define LDD_USB_ON_HOST_DEVICE_DEATTACH 0x00000100u /*!< OnHostDeviceAttach event mask */ +#define LDD_USB_ON_HOST_RESET_RECOVERY 0x00000200u /*!< OnHostResetRecovery event mask */ +#define LDD_USB_ON_HOST_RESUME_RECOVERY 0x00000400u /*!< OnHostResumeRecovery event mask */ +#define LDD_USB_ON_HOST_1MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_1_MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_ERROR 0x00001000u /*!< OnHostError event mask */ +#define LDD_USB_ON_OTG_DEVICE 0x00002000u /*!< OnOtgDevice event mask */ +#define LDD_USB_ON_OTG_HOST 0x00004000u /*!< OnOtgHost event mask */ +#define LDD_USB_ON_OTG_STATE_CHANGE 0x00008000u /*!< OnOtgStageChange event mask */ +#define LDD_USB_ON_SIGNAL_CHANGE 0x00010000u /*!< OnSignalChange event mask */ + +/* Data pins' masks */ +#define LDD_USB_DP_PIN 0x00000001u /*!< Data+ pin mask */ +#define LDD_USB_DM_PIN 0x00000002u /*!< Data- pin mask */ + +/* Pullup/pulldown pin masks */ +#define LDD_USB_DP_PU_PIN 0x00000004u /*!< Data+ pull-up pin mask */ +#define LDD_USB_DM_PU_PIN 0x00000008u /*!< Data- pull-up pin mask */ +#define LDD_USB_DP_PD_PIN 0x00000010u /*!< Data+ pull-down pin mask */ +#define LDD_USB_DM_PD_PIN 0x00000020u /*!< Data- pull-down pin mask */ + +/* VBUS pins' mask */ +#define LDD_USB_DEVICE_VBUS_DETECT_PIN 0x00000040u /*!< VBUS detect pin mask */ +#define LDD_USB_HOST_VBUS_ENABLE_PIN 0x00000080u /*!< VBUS enable pin mask */ +#define LDD_USB_HOST_VBUS_OVERCURRENT_PIN 0x00000100u /*!< VBUS overcurrent pin mask */ + +/* OTG pins' masks */ +#define LDD_USB_OTG_ID_PIN 0x00000200u /*!< ID pin mask */ +#define LDD_USB_OTG_VBUS_VALID_PIN 0x00000400u /*!< VBUS valid pin mask */ +#define LDD_USB_OTG_SESSION_VALID_PIN 0x00000800u /*!< SESSION valid pin mask */ +#define LDD_USB_OTG_B_SESSION_END_PIN 0x00004000u /*!< B SESSION end pin mask */ +#define LDD_USB_OTG_VBUS_ENABLE_PIN 0x00008000u /*!< VBUS drive pin mask */ +#define LDD_USB_OTG_VBUS_CHARGE_PIN 0x00010000u /*!< VBUS charge pin mask */ +#define LDD_USB_OTG_VBUS_DISCHARGE_PIN 0x00020000u /*!< VBUS discharge pin mask */ + +/* ULPI pins' masks */ +#define LDD_USB_ULPI_CLK_PIN 0x00080000u /*!< ULPI_CLK pin mask */ +#define LDD_USB_ULPI_DIR_PIN 0x00100000u /*!< ULPI_DIR pin mask */ +#define LDD_USB_ULPI_NXT_PIN 0x00200000u /*!< ULPI_NXT pin mask */ +#define LDD_USB_ULPI_STP_PIN 0x00400000u /*!< ULPI_STOP pin mask */ +#define LDD_USB_ULPI_DATA_0_PIN 0x00800000u /*!< ULPI_DATA_0 pin mask */ +#define LDD_USB_ULPI_DATA_1_PIN 0x01000000u /*!< ULPI_DATA_1 pin mask */ +#define LDD_USB_ULPI_DATA_2_PIN 0x02000000u /*!< ULPI_DATA_2 pin mask */ +#define LDD_USB_ULPI_DATA_3_PIN 0x04000000u /*!< ULPI_DATA_3 pin mask */ +#define LDD_USB_ULPI_DATA_4_PIN 0x08000000u /*!< ULPI_DATA_4 pin mask */ +#define LDD_USB_ULPI_DATA_5_PIN 0x10000000u /*!< ULPI_DATA_5 pin mask */ +#define LDD_USB_ULPI_DATA_6_PIN 0x20000000u /*!< ULPI_DATA_6 pin mask */ +#define LDD_USB_ULPI_DATA_7_PIN 0x40000000u /*!< ULPI_DATA_7 pin mask */ + +/* Alternate clock pin*/ +#define LDD_USB_CLKIN_PIN 0x80000000u /*!< Alternate clock pin mask */ +#define LDD_USB_ALT_CLK_PIN 0x80000000u /*!< Alternate clock pin mask */ + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Cmd/CmdStatusPtr param. values */ +#define LDD_USB_CMD_GET_EP_STATUS 0x00u /*!< Get endpoint status command ID */ +#define LDD_USB_CMD_SET_EP_HALT_FATURE 0x01u /*!< Set endpoint HALT feature command ID */ +#define LDD_USB_CMD_CLR_EP_HALT_FATURE 0x02u /*!< Clear endpoint HALT feature command ID */ + +#define LDD_USB_CMD_EP_STATUS_HALT_MASK 0x01u /*!< Endpoint halt status mask */ + + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Recipient param. values */ +/* (see USB 2.0, chapter 9.3.4 wIndex description)*/ +#define LDD_USB_ID_EP0_OUT 0x00u /*!< EP0 OUT component ID */ +#define LDD_USB_ID_EP0_IN 0x80u /*!< EP0 IN component ID */ +#define LDD_USB_ID_EP1_OUT 0x01u /*!< EP1 OUT component ID */ +#define LDD_USB_ID_EP1_IN 0x81u /*!< EP1 IN component ID */ +#define LDD_USB_ID_EP2_OUT 0x02u /*!< EP2 OUT component ID */ +#define LDD_USB_ID_EP2_IN 0x82u /*!< EP2 IN component ID */ +#define LDD_USB_ID_EP3_OUT 0x03u /*!< EP3 OUT component ID */ +#define LDD_USB_ID_EP3_IN 0x83u /*!< EP3 IN component ID */ +#define LDD_USB_ID_EP4_OUT 0x04u /*!< EP4 OUT component ID */ +#define LDD_USB_ID_EP4_IN 0x84u /*!< EP4 IN component ID */ +#define LDD_USB_ID_EP5_OUT 0x05u /*!< EP5 OUT component ID */ +#define LDD_USB_ID_EP5_IN 0x85u /*!< EP5 IN component ID */ +#define LDD_USB_ID_EP6_OUT 0x06u /*!< EP6 OUT component ID */ +#define LDD_USB_ID_EP6_IN 0x86u /*!< EP6 IN component ID */ +#define LDD_USB_ID_EP7_OUT 0x07u /*!< EP7 OUT component ID */ +#define LDD_USB_ID_EP7_IN 0x87u /*!< EP7 IN component ID */ +#define LDD_USB_ID_EP8_OUT 0x08u /*!< EP8 OUT component ID */ +#define LDD_USB_ID_EP8_IN 0x88u /*!< EP8 IN component ID */ +#define LDD_USB_ID_EP9_OUT 0x09u /*!< EP9 OUT component ID */ +#define LDD_USB_ID_EP9_IN 0x89u /*!< EP9 IN component ID */ +#define LDD_USB_ID_EP10_OUT 0x0Au /*!< EP10 OUT component ID */ +#define LDD_USB_ID_EP10_IN 0x8Au /*!< EP10 IN component ID */ +#define LDD_USB_ID_EP11_OUT 0x0Bu /*!< EP11 OUT component ID */ +#define LDD_USB_ID_EP11_IN 0x8Bu /*!< EP11 IN component ID */ +#define LDD_USB_ID_EP12_OUT 0x0Cu /*!< EP12 OUT component ID */ +#define LDD_USB_ID_EP12_IN 0x8Cu /*!< EP12 IN component ID */ +#define LDD_USB_ID_EP13_OUT 0x0Du /*!< EP13 OUT component ID */ +#define LDD_USB_ID_EP13_IN 0x8Du /*!< EP13 IN component ID */ +#define LDD_USB_ID_EP14_OUT 0x0Eu /*!< EP14 OUT component ID */ +#define LDD_USB_ID_EP14_IN 0x8Eu /*!< EP14 IN component ID */ +#define LDD_USB_ID_EP15_OUT 0x0Fu /*!< EP15 OUT component ID */ +#define LDD_USB_ID_EP15_IN 0x8Fu /*!< EP15 IN component ID */ +#define LDD_USB_ID_EP_MASK 0x8Fu /*!< EP15 IN component ID */ + +/* Token PID */ +#define LDD_USB_PID_OUT 0x01u /*!< OUT */ +#define LDD_USB_PID_IN 0x09u /*!< IN */ +#define LDD_USB_PID_SOF 0x05u /*!< SOF */ +#define LDD_USB_PID_SETUP 0x0Du /*!< SETUP */ +/* Data PID */ +#define LDD_USB_PID_DATA0 0x03u /*!< DATA0 */ +#define LDD_USB_PID_DATA1 0x0Bu /*!< DATA1 */ +#define LDD_USB_PID_DATA2 0x07u /*!< DATA2 */ +#define LDD_USB_PID_MDATA 0x0Fu /*!< MDATA */ +/* Handshake PID */ +#define LDD_USB_PID_ACK 0x02u /*!< ACK */ +#define LDD_USB_PID_NACK 0x0Au /*!< NACK */ +#define LDD_USB_PID_STALL 0x0Eu /*!< STALL */ +#define LDD_USB_PID_NYET 0x06u /*!< NYET */ +/* Special PID */ +#define LDD_USB_PID_PRE 0x0Cu /*!< PRE */ +#define LDD_USB_PID_ERR 0x0Cu /*!< ERR */ +#define LDD_USB_PID_SPLIT 0x08u /*!< SPLIT */ +#define LDD_USB_PID_PING 0x04u /*!< PING */ + +/* Data direction */ +#define LDD_USB_DIR_OUT 0x00u /*!< Recipient is Device */ +#define LDD_USB_DIR_IN 0x80u /*!< Recipient is Host */ +#define LDD_USB_DIR_MASK 0x80u /*!< Bit mask for data transfer direction */ + +/* Flags used in the TD.Head.Flags variable */ + +/* The following flag can be used to force zero-length termination(ZLT) of the transfer. + Note: ZLT can be set for all transfer during the initialization of the endpoint. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_ZLT 0x01u + +/* If the TRANSFER_FLAG_EXT_PARAM is defined all variables of the TD are used + and TD must NOT be freed until transfer is done or is cancelled + (TransferState != LDD_USB_TRANSFER_PENDING) + If not defined only the Head member of TD is used and TD can be freed after + Send/Recv() method returns. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM 0x02u + + +#define ERR_COMPONET_SPECIFIC 0x100u + +/* Device mode USB specific error codes */ +#define ERR_USB_DEVICE_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Device mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_DEVICE_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Device mode is disabled by the OTG driver */ +#define ERR_USB_DEVICE_VBUS_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< No VBUS is detected */ +#define ERR_USB_DEVICE_VBUS_ON (ERR_COMPONET_SPECIFIC + 0x03u) /*!< VBUS is detected */ +#define ERR_USB_DEVICE_ENABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is enabled */ +#define ERR_USB_DEVICE_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Device is suspended */ +#define ERR_USB_DEVICE_SUSPENDED_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Device is suspended and ready to generate resume signaling */ +#define ERR_USB_DEVICE_RESUME_PENDING (ERR_COMPONET_SPECIFIC + 0x07u) /*!< Device generates resume signaling */ + +/* Host mode USB specific error codes */ +#define ERR_USB_HOST_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Host mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_HOST_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Host mode is disabled by the OTG driver */ +#define ERR_USB_HOST_PORT_POWERED_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< Port is power off */ +#define ERR_USB_HOST_PORT_DISCONNECTED (ERR_COMPONET_SPECIFIC + 0x03u) /*!< Port is power on */ +#define ERR_USB_HOST_PORT_DISABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is connected to the port */ +#define ERR_USB_HOST_PORT_RESETING (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Port generates reset signaling */ +#define ERR_USB_HOST_PORT_RESET_RECOVERING (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Port waits 10ms for reset recovery */ +#define ERR_USB_HOST_PORT_ENABLED (ERR_COMPONET_SPECIFIC + 0x07u) /*!< PortDevice is connected, reset and ready to use */ +#define ERR_USB_HOST_PORT_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x08u) /*!< Port is suspended */ +#define ERR_USB_HOST_PORT_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x09u) /*!< Port can generate resume signaling */ +#define ERR_USB_HOST_PORT_RESUMING (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< Port generates resume signaling */ +#define ERR_USB_HOST_PORT_RESUME_RECOVERING (ERR_COMPONET_SPECIFIC + 0x0Bu) /*!< Port generates resume signaling */ + +/* OTG mode USB specific error codes */ +#define ERR_USB_OTG_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< OTG device is DISABLED state */ +#define ERR_USB_OTG_ENABLED_PENDING (ERR_COMPONET_SPECIFIC + 0x01u) /*!< OTG device is in ENABLED_PENDING state */ +#define ERR_USB_OTG_A_IDLE (ERR_COMPONET_SPECIFIC + 0x02u) /*!< OTG device is in A_IDLE state */ +#define ERR_USB_OTG_A_WAIT_VRISE (ERR_COMPONET_SPECIFIC + 0x03u) /*!< OTG device is in WAIT_VRISE state */ +#define ERR_USB_OTG_A_WAIT_VFALL (ERR_COMPONET_SPECIFIC + 0x05u) /*!< OTG device is in A_WAIT_VFALL state */ +#define ERR_USB_OTG_A_WAIT_BCON (ERR_COMPONET_SPECIFIC + 0x07u) /*!< OTG device is in A_WAIT_BCON state */ +#define ERR_USB_OTG_A_VBUS_ERROR (ERR_COMPONET_SPECIFIC + 0x09u) /*!< OTG device is in A_VBUS_ERROR state */ +#define ERR_USB_OTG_A_SUSPEND (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< OTG device is in A_SUSPEND state */ + +#define ERR_USB_OTG_B_IDLE (ERR_COMPONET_SPECIFIC + 0x0Cu) /*!< OTG device is in B_IDLE state */ +#define ERR_USB_OTG_B_SRP_INIT (ERR_COMPONET_SPECIFIC + 0x0Eu) /*!< OTG device is in B_SRP_INIT state */ +#define ERR_USB_OTG_B_WAIT_ACON (ERR_COMPONET_SPECIFIC + 0x0Fu) /*!< OTG device is in B_WAIT_ACON state */ + +#define ERR_USB_OTG_A_HOST (ERR_COMPONET_SPECIFIC + 0x10u) /*!< OTG device is in A_HOST state */ +#define ERR_USB_OTG_A_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x11u) /*!< OTG device is in A_PERIPHERAL state */ +#define ERR_USB_OTG_B_HOST (ERR_COMPONET_SPECIFIC + 0x12u) /*!< OTG device is in B_HOST state */ +#define ERR_USB_OTG_B_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x13u) /*!< OTG device is in B_PERIPHERAL state */ + +/*! Device speed symbolic names */ +typedef enum { + LDD_USB_LOW_SPEED = 0x00u, /*!< Low-speed - 6 Mb/s mode */ + LDD_USB_FULL_SPEED = 0x01u, /*!< Full-speed - 12 Mb/s mode */ + LDD_USB_HIGH_SPEED = 0x02u, /*!< High-speed - 480 Mb/s mode */ + LDD_USB_SPEED_UNKNOWN = 0xFFu /*!< Unkown speed mode */ +} LDD_USB_TBusSpeed; + +/*! Transfer type symbolic names */ +typedef enum { + LDD_USB_CONTROL = 0x00u, /*!< Conrol transfer type */ + LDD_USB_ISOCHRONOUS = 0x01u, /*!< Isochronous transfer type */ + LDD_USB_BULK = 0x02u, /*!< Bulk transfer type */ + LDD_USB_INTERRUPT = 0x03u /*!< Interrupt transfer type */ +} LDD_USB_TTransferType; + +/*! Transfer state symbolic names */ +typedef enum { + LDD_USB_TRANSFER_NONE = 0x00u, /*!< Default valeu for new TD */ + LDD_USB_TRANSFER_DONE = 0x01u, /*!< Transfer done */ + LDD_USB_TRANSFER_ERROR_CANCELLED = 0x02u, /*!< Transfer cancelled by the user */ + LDD_USB_TRANSFER_ERROR_STALLED = 0x03u, /*!< Transfer stalled */ + LDD_USB_TRANSFER_ERROR_BUS_TIMEOUT = 0x04u, /*!< Bus timeute detected */ + LDD_USB_TRANSFER_ERROR_DATA = 0x05u, /*!< Data error deteceted */ + LDD_USB_TRANSFER_ERROR_PID = 0x06u, /*!< PID error deteceted */ + LDD_USB_TRANSFER_ERROR_EOF = 0x07u, /*!< EOF error deteceted */ + LDD_USB_TRANSFER_ERROR_CRC16 = 0x08u, /*!< CRC16 error deteceted */ + LDD_USB_TRANSFER_ERROR_DFN8 = 0x09u, /*!< DFN8 error deteceted */ + LDD_USB_TRANSFER_ERROR_DMA = 0x0Au, /*!< DMA error deteceted */ + LDD_USB_TRANSFER_ERROR_BTS = 0x0Bu, /*!< BTS error deteceted */ + LDD_USB_TRANSFER_ERROR = 0x0Fu, /*!< Transfer error deteceted */ + LDD_USB_TRANSFER_QUEUED = 0x10u, /*!< Transfer queued */ + LDD_USB_TRANSFER_PENDING = 0x30u /*!< Transfer in proggress */ +} LDD_USB_TTransferState; + +/*! Setup data packet structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TSDP_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request code */ + uint16_t wValue; /*!< Word-sized field that varies according to request */ + uint16_t wIndex; /*!< Word-sized field that varies according to request, typically used to pass an index or offset */ + uint16_t wLength; /*!< Number of bytes to transfer if there is a data stage */ +} LDD_USB_TSDP; + +/*! Endpoint descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TEpDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint8_t bEndpointAddress; /*!< Endpoint address */ + uint8_t bmAttributes; /*!< Endpoint attributes */ + uint16_t wMaxPacketSize; /*!< Maximum packet size the endpoint is capable of sending or receiving */ + uint8_t bInterval; /*!< Interval for polling endpoint for data transfers */ +} LDD_USB_TEpDescriptor; + +/*! Standard device descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TDevDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t bcdUSB; /*!< USB specification release number in binary-coded Decimal */ + uint8_t bDeviceClass; /*!< Class code (assigned by the USB-IF) */ + uint8_t bDeviceSubClass; /*!< Subclass code (assigned by the USB-IF) */ + uint8_t bDeviceProtocol; /*!< Protocol code (assigned by the USB-IF) */ + uint8_t bMaxPacketSize0; /*!< Maximum packet size for endpoint zero */ + uint16_t idVendor; /*!< Vendor ID (assigned by the USB-IF) */ + uint16_t idProduct; /*!< Product ID (assigned by the manufacturer) */ + uint16_t bcdDevice; /*!< Device release number in binary-coded decimal */ + uint8_t iManufacturer; /*!< Index of string descriptor describing manufacturer */ + uint8_t iProduct; /*!< Index of string descriptor describing product */ + uint8_t iSerialNumber; /*!< Index of string descriptor describing the device’s serial number */ + uint8_t bNumConfigurations; /*!< Number of possible configurations */ +} LDD_USB_TDevDescriptor; + + +/*! Device transfer descriptor structure forward declaration */ +struct LDD_USB_Device_TTD_Struct; + +/*! Device transfer done callback prototype */ +typedef void (LDD_USB_Device_TTransferDoneCalback)(LDD_TDeviceData *DevDataPtr, struct LDD_USB_Device_TTD_Struct *TrParamPtr); + +/*! Device transfer descriptor structure - head part */ +typedef struct LDD_USB_Device_TTD_Head_Struct { + uint8_t EpNum; /*!< Endpoint number */ + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags - see constants definition */ +} LDD_USB_Device_TTD_Head; + +/*! Device transfer descriptor structure */ +typedef struct LDD_USB_Device_TTD_Struct { + /* Requierd variables */ + LDD_USB_Device_TTD_Head Head; /*!< Td head data, not changed by the driver */ + /* Optional items - the following items are used */ + /* only if Head.Flags & LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM != 0 */ + LDD_USB_TTransferState TransferState; /*!< Transfer state. Set by the driver */ + uint16_t TransmittedDataSize; /*!< Transmitted data size. Set by the driver */ + LDD_USB_Device_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ +} LDD_USB_Device_TTD; + +/*! USB device states symbolic names */ +typedef enum { + LDD_USB_DEVICE_DISABLED = ERR_USB_DEVICE_DISABLED, /*!< Device mode is disabled (by the user or by the clock configuration) */ + LDD_USB_DEVICE_DISABLED_BY_OTG = ERR_USB_DEVICE_DISABLED_BY_OTG, /*!< Device mode is disabled by the OTG driver */ + LDD_USB_DEVICE_VBUS_OFF = ERR_USB_DEVICE_VBUS_OFF, /*!< No VBUS is detected */ + LDD_USB_DEVICE_VBUS_ON = ERR_USB_DEVICE_VBUS_ON, /*!< VBUS is detected */ + LDD_USB_DEVICE_ENABLED = ERR_USB_DEVICE_ENABLED, /*!< Device is enabled - reset by the host */ + LDD_USB_DEVICE_SUSPENDED = ERR_USB_DEVICE_SUSPENDED, /*!< Device is suspended - Bus is idle more then 3 ms */ + LDD_USB_DEVICE_SUSPENDED_RESUME_READY = ERR_USB_DEVICE_SUSPENDED_RESUME_READY, /*!< Device can generate resume signaling - Bus is idle more then 5 ms. */ + LDD_USB_DEVICE_RESUME_PENDING = ERR_USB_DEVICE_RESUME_PENDING /*!< Device generates resume signaling */ +} LDD_USB_Device_TState; + +/*! USB host mode states symbolic names */ +typedef enum { + LDD_USB_HOST_DISABLED = ERR_USB_HOST_DISABLED, /*!< Host mode is disabled (by the user or by the clock configuration) */ + LDD_USB_HOST_DISABLED_BY_OTG = ERR_USB_HOST_DISABLED_BY_OTG, /*!< Host mode is disabled by the OTG driver */ + LDD_USB_HOST_PORT_POWERED_OFF = ERR_USB_HOST_PORT_POWERED_OFF, /*!< Port is powered-off */ + LDD_USB_HOST_PORT_DISCONNECTED = ERR_USB_HOST_PORT_DISCONNECTED, /*!< No device is connected */ + LDD_USB_HOST_PORT_DISABLED = ERR_USB_HOST_PORT_DISABLED, /*!< Device is connected to the port */ + LDD_USB_HOST_PORT_RESETING = ERR_USB_HOST_PORT_RESETING, /*!< Port generates reset signaling */ + LDD_USB_HOST_PORT_RESET_RECOVERING = ERR_USB_HOST_PORT_RESET_RECOVERING, /*!< Port waits 10 ms for reset recovery */ + LDD_USB_HOST_PORT_ENABLED = ERR_USB_HOST_PORT_ENABLED, /*!< Device is connected, reset and ready to use */ + LDD_USB_HOST_PORT_SUSPENDED = ERR_USB_HOST_PORT_SUSPENDED, /*!< Port is suspended */ + LDD_USB_HOST_PORT_RESUME_READY = ERR_USB_HOST_PORT_RESUME_READY, /*!< Port is ready to generate resume signaling */ + LDD_USB_HOST_PORT_RESUMING = ERR_USB_HOST_PORT_RESUMING, /*!< Port generates resume signaling */ + LDD_USB_HOST_PORT_RESUME_RECOVERING = ERR_USB_HOST_PORT_RESUME_RECOVERING /*!< Port waits 10 ms for resume recovery */ +} LDD_USB_Host_TState; + +/*! USB otg mode states symbolic names */ +typedef enum { + LDD_USB_OTG_DISABLED = ERR_USB_OTG_DISABLED, /*!< OTG device is in DISABLED state */ + LDD_USB_OTG_ENABLED = ERR_USB_OTG_ENABLED_PENDING, /*!< OTG device is in ENABLED_PENDING state */ + LDD_USB_OTG_A_IDLE = ERR_USB_OTG_A_IDLE, /*!< OTG device is in A_IDLE state */ + LDD_USB_OTG_A_WAIT_VRISE = ERR_USB_OTG_A_WAIT_VRISE, /*!< OTG device is in A_WAIT_VRISE state */ + LDD_USB_OTG_A_WAIT_VFALL = ERR_USB_OTG_A_WAIT_VFALL, /*!< OTG device is in A_WAIT_VFALL state */ + LDD_USB_OTG_A_WAIT_BCON = ERR_USB_OTG_A_WAIT_BCON, /*!< OTG device is in A_WAIT_BCON state */ + LDD_USB_OTG_A_VBUS_ERROR = ERR_USB_OTG_A_VBUS_ERROR, /*!< OTG device is in A_VBUS_ERROR state */ + LDD_USB_OTG_A_SUSPEND = ERR_USB_OTG_A_SUSPEND, /*!< OTG device is in A_SUSPEND state */ + LDD_USB_OTG_B_IDLE = ERR_USB_OTG_B_IDLE, /*!< OTG device is in B_IDLE state */ + LDD_USB_OTG_B_SRP_INIT = ERR_USB_OTG_B_SRP_INIT, /*!< OTG device is in B_SRP_INIT state */ + LDD_USB_OTG_B_WAIT_ACON = ERR_USB_OTG_B_WAIT_ACON, /*!< OTG device is in B_WAIT_ACON state */ + LDD_USB_OTG_A_HOST = ERR_USB_OTG_A_HOST, /*!< OTG device is in A_HOST state */ + LDD_USB_OTG_A_PERIPHERAL = ERR_USB_OTG_A_PERIPHERAL, /*!< OTG device is in A_PERIPHERAL state */ + LDD_USB_OTG_B_HOST = ERR_USB_OTG_B_HOST, /*!< OTG device is in B_HOST state */ + LDD_USB_OTG_B_PERIPHERAL = ERR_USB_OTG_B_PERIPHERAL /*!< OTG device is in B_PERIPHERAL state */ +} LDD_USB_Otg_TState; + +/*! USB Otg commands symbolic names */ +typedef enum { + LDD_USB_OTG_CMD_SET_A_BUS_REQUEST, /*!< A-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_REQUEST, /*!< A-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_B_BUS_REQUEST, /*!< B-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_B_BUS_REQUEST, /*!< B-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_A_BUS_DROP, /*!< A-device application needs to power down the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_DROP, /*!< A-device application doesn't need to power down the bus */ + LDD_USB_OTG_CMD_SET_A_SUSPEND_REQUEST, /*!< A-device application wants to suspend the bus */ + LDD_USB_OTG_CMD_CLR_A_SUSPEND_REQUEST, /*!< A-device application doesn't want to suspend the bus */ + LDD_USB_OTG_CMD_SET_A_SET_B_HNP_EN_REQUEST, /*!< A-device sets HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_CLR_A_SET_B_HNP_EN_REQUEST, /*!< A-device clears HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_SET_B_HNP_EN_REQUEST, /*!< Enable B-device HNP */ + LDD_USB_OTG_CMD_CLR_B_HNP_EN_REQUEST /*!< Disable B-device HNP */ +} LDD_USB_Otg_TCmd; + +/*! USB host port control commands symbolic names */ +typedef enum { + LDD_USB_HOST_PORT_CMD_POWER_ON, /*!< Power-on the bus */ + LDD_USB_HOST_PORT_CMD_POWER_OFF, /*!< Power-off the bus */ + LDD_USB_HOST_PORT_CMD_RESET, /*!< Perform the bus reset signaling and call event after the reset recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_RESUME, /*!< Perform the bus resume signaling and call event after the resume recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_SUSPEND, /*!< Suspend the bus and transceiver */ + LDD_USB_HOST_PORT_CMD_DISABLE /*!< Disable the port */ +} LDD_USB_Host_TPortControlCmd; + +/*! USB host handle prototypes */ +typedef void LDD_USB_Host_TPipeHandle; /*!< Pipe handle prototype */ +typedef void LDD_USB_Host_TTransferHandle; /*!< Transfer handle prototype */ + +/*! USB host pipe descriptor structure */ +typedef struct LDD_USB_Host_TPipeDescr_Struct { + uint8_t DevAddress; /*!< Device address */ + LDD_USB_TBusSpeed DevSpeed; /*!< Device speed */ + uint8_t EpNumber; /*!< EP number */ + uint8_t EpDir; /*!< EP direction */ + LDD_USB_TTransferType TransferType; /*!< EP Transfer type */ + uint16_t MaxPacketSize; /*!< EP max. packet size */ + uint8_t TrPerUFrame; /*!< Transaction pre microframe */ + uint32_t Interval; /*!< Interval for polling endpoint for data transfers */ + uint32_t NAKCount; /*!< NAK count */ + uint8_t Flags; /*!< 1 = ZLT */ +} LDD_USB_Host_TPipeDescr; + +/*! USB host transfer done callback prototype */ +typedef void (LDD_USB_Host_TTransferDoneCalback)( + LDD_TDeviceData *DevDataPtr, /*!< User value passed as parameter of the Init() method */ + LDD_TData *BufferPtr, /*!< Buffer address */ + uint16_t BufferSize, /*!< Transferred data size */ + uint8_t *ParamPtr, /*!< User value passed in Send()/Recv() method */ + LDD_USB_TTransferState Status /*!< Transfer status */ +); + +/*! USB host transfer descriptor structure */ +typedef struct LDD_USB_Host_TTD_Struct { + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags */ + LDD_USB_Host_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ + LDD_USB_TSDP *SDPPrt; /*!< Setup data buffer pointer */ +} LDD_USB_Host_TTD; + +/*! Following USB constants and types are for test purpose only */ + +/* Request types */ +#define LDD_USB_REQ_TYPE_STANDARD 0x00u /*!< Standard request */ +#define LDD_USB_REQ_TYPE_CLASS 0x20u /*!< Class request */ +#define LDD_USB_REQ_TYPE_VENDOR 0x40u /*!< Vendor request */ +#define LDD_USB_REQ_TYPE_MASK 0x60u /*!< Bit mask for request type (bmRequestType) */ + +/* Request recepient */ +#define LDD_USB_REQ_RECP_DEVICE 0x00u /*!< Recipient = Device */ +#define LDD_USB_REQ_RECP_INTERFACE 0x01u /*!< Recipient = Interface */ +#define LDD_USB_REQ_RECP_ENDPOINT 0x02u /*!< Recipient = Endpoint */ +#define LDD_USB_REQ_RECP_OTHER 0x03u /*!< Recipient = Other */ +#define LDD_USB_REQ_RECP_MASK 0x03u /*!< Bit mask for recipient */ + +/* Standard request codes (bRequest) */ +#define LDD_USB_REQ_GET_STATUS 0x00u /*!< GET_STATUS request code */ +#define LDD_USB_REQ_CLEAR_FEATURE 0x01u /*!< CLEAR_FEATURE request code */ +#define LDD_USB_REQ_SET_FEATURE 0x03u /*!< SET_FEATURE request code */ +#define LDD_USB_REQ_GET_STATE 0x04u /*!< GET_STATE request code (for Hub Class only)*/ +#define LDD_USB_REQ_SET_ADDRESS 0x05u /*!< SET_ADDRESS request code */ +#define LDD_USB_REQ_GET_DESCRIPTOR 0x06u /*!< GET_DESCRIPTOR request code */ +#define LDD_USB_REQ_SET_DESCRIPTOR 0x07u /*!< SET_DESCRIPTOR request code, this request is not supported */ +#define LDD_USB_REQ_GET_CONFIGURATION 0x08u /*!< GET_CONFIGURATION request code */ +#define LDD_USB_REQ_SET_CONFIGURATION 0x09u /*!< SET_CONFIGURATION request code */ +#define LDD_USB_REQ_GET_INTERFACE 0x0Au /*!< GET_INTERFACE request code */ +#define LDD_USB_REQ_SET_INTERFACE 0x0Bu /*!< SET_INTERFACE request code */ +#define LDD_USB_REQ_SYNCH_FRAME 0x0Cu /*!< SYNCH_FRAME request code */ + +/* Standard request words for device (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_DEV_STATUS 0x0080u /*!< GET_DEVICE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_DEV_FEATURE 0x0100u /*!< CLEAR_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DEV_FEATURE 0x0300u /*!< SET_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_ADDRESS 0x0500u /*!< SET_DEVICE_ADDRESS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_DESCRIPTOR 0x0680u /*!< GET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DESCRIPTOR 0x0700u /*!< SET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_CONFIGURATION 0x0880u /*!< GET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_CONFIGURATION 0x0900u /*!< SET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ + +/* Standard request words for interface (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_INT_STATUS 0x0081u /*!< GET_INTERFACE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_INT_FEATURE 0x0101u /*!< CLEAR_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INT_FEATURE 0x0301u /*!< SET_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_INTERFACE 0x0A81u /*!< GET_DEVICE_INTERFACE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INTERFACE 0x0B01u /*!< SET_DEVICE_INTERFACE bmRequestType and bRequest word */ + +/* Standard request words for endpoint (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_EP_STATUS 0x0082u /*!< GET_ENDPOINT_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_EP_FEATURE 0x0102u /*!< CLEAR_ENDPOINT_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_EP_FEATURE 0x0302u /*!< ENDPOINT_ bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SYNCH_FRAME 0x0C12u /*!< SYNCH_DEVICE_FRAME bmRequestType and bRequest code */ + +#define LDD_USB_STATUS_DEVICE_SELF_POWERED_MASK 0x01u +#define LDD_USB_STATUS_DEVICE_REMOTE_WAKEUP_MASK 0x02u + +/* Standard descriptors */ +#define LDD_USB_DT_DEVICE 0x01u /*!< Device descriptor */ +#define LDD_USB_DT_CONFIGURATION 0x02u /*!< Configuration descriptor */ +#define LDD_USB_DT_STRING 0x03u /*!< String descriptor */ +#define LDD_USB_DT_INTERFACE 0x04u /*!< Interface descriptor */ +#define LDD_USB_DT_ENDPOINT 0x05u /*!< Endpoint descriptor */ +#define LDD_USB_DT_DEVICE_QUALIFIER 0x06u /*!< Device qualifier descriptor */ +#define LDD_USB_DT_OTHER_SPEED_CONFIGURATION 0x07u /*!< Other speed configuration descriptor */ +#define LDD_USB_DT_INTERFACE_POWER 0x08u /*!< Interface-level power management descriptor */ +#define LDD_USB_DT_OTG 0x09u /*!< OTG descriptor */ +#define LDD_USB_DT_DEBUG 0x0Au /*!< Debug descriptor */ +#define LDD_USB_DT_INTERFACE_ASSOCIATION 0x0Bu /*!< Interface association descriptor */ + +/* Standard feature selectors */ +#define LDD_USB_FEATURE_EP_HALT 0x00u /*!< Endpoint HALT feature selector */ +#define LDD_USB_FEATURE_DEV_REMOTE_WAKEUP 0x01u /*!< Remote Wake-up feature selector */ +#define LDD_USB_FEATURE_DEV_TEST_MODE 0x02u /*!< Test mode feature selector */ + +/*! Get decriptor request structure */ +typedef struct LDD_USB_TGetDecriptorRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bDescriptorIndex; /*!< Descriptor index */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t wLanguageID; /*!< Language ID */ + uint16_t wLength; /*!< Requested data size */ +} LDD_USB_TGetDecriptorRequest; + +/*! Get endpoint status request structure */ +typedef struct LDD_USB_TEndpointStatusRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wValue; /*!< Not used, should be set to zero */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Reqested data size, should be set to 2 */ +} LDD_USB_TEndpointStatusRequest; + +/*! Clear/Set endpoint feature request structure */ +typedef struct LDD_USB_TEndpointFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TEndpointFeatureRequest; + +/*! Clear/Set interface request structure */ +typedef struct LDD_USB_TInterfaceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TInterfaceFeatureRequest; + +/*! Clear/Set device request structure */ +typedef struct LDD_USB_TDeviceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TDeviceFeatureRequest; + +/*! Get interface request structure */ +typedef struct LDD_USB_TGetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wWalue; /*!< Not used, should be zero */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Reqested data size, should be set to 1 */ +} LDD_USB_TGetInterfaceRequest; + +/*! Set interface request structure */ +typedef struct LDD_USB_TSetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wAltSet; /*!< Alternate setting */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetInterfaceRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetAddressRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t DeviceAddress; /*!< Device address */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetAddressRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetConfigRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint8_t ConfigNumber; /*!< Configuration number */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetConfigRequest; + +/* +** =================================================================== +** DAC device types and constants +** =================================================================== +*/ +#define LDD_DAC_OUTPUT_PIN_0 0x01u /*!< DAC output pin 0 mask */ + +#define LDD_DAC_ON_BUFFER_END 0x01U /*!< OnBufferEnd event mask */ +#define LDD_DAC_ON_BUFFER_START 0x02U /*!< OnBufferStart event mask */ +#define LDD_DAC_ON_BUFFER_WATERMARK 0x04U /*!< OnBufferWatermark event mask */ +#define LDD_DAC_ON_COMPLETE LDD_DMA_ON_COMPLETE /*!< OnComplete event mask */ +#define LDD_DAC_ON_ERROR LDD_DMA_ON_ERROR /*!< OnError event mask */ + +/*! Type specifying the DAC buffer work mode */ +typedef enum { + LDD_DAC_BUFFER_NORMAL_MODE = 0x00U, /*!< Normal (cyclic) mode */ + LDD_DAC_BUFFER_SWING_MODE = 0x01U, /*!< Swing mode */ + LDD_DAC_BUFFER_SCAN_MODE = 0x02U /*!< One-time scan mode */ +} LDD_DAC_TBufferMode; + +/*! Type specifying the DAC buffer watermark levels */ +typedef enum { + LDD_DAC_BUFFER_WATERMARK_L1 = 0x00U, + LDD_DAC_BUFFER_WATERMARK_L2 = 0x01U, + LDD_DAC_BUFFER_WATERMARK_L3 = 0x02U, + LDD_DAC_BUFFER_WATERMARK_L4 = 0x03U +} LDD_DAC_TBufferWatermark; + +#define LDD_DAC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef void* LDD_DAC_TDataPtr; /*!< Type specifying the pointer to the DAC data variable */ +typedef uint32_t LDD_DAC_TData; /*!< The DAC data variable type */ +typedef uint32_t LDD_DAC_TErrorMask; /*!< Error mask */ +typedef uint32_t LDD_DAC_TArrayLength; /*!< Array length type */ + +/* +** =================================================================== +** FLASH device types and constants +** =================================================================== +*/ +#define LDD_FLASH_ON_OPERATION_COMPLETE 0x02u /*!< OnOperationComplete event mask */ +#define LDD_FLASH_ON_ERROR 0x04u /*!< OnError event mask */ + +#define LDD_FLASH_READ_COLLISION_ERROR 0x40u /*!< Read collision error flag's mask */ +#define LDD_FLASH_ACCESS_ERROR 0x20u /*!< Access error flag's mask */ +#define LDD_FLASH_PROTECTION_VIOLATION 0x10u /*!< Protection violation error flag's mask */ +#define LDD_FLASH_ERASE_VERIFICATION_ERROR 0x08u /*!< Erase verification error flag's mask */ +#define LDD_FLASH_MULTIPLE_WRITE_ERROR 0x04u /*!< Multiple write to one flash memory location error flag's mask */ + +/*! Type specifying HW commands for a flash device */ +typedef enum { + LDD_FLASH_READ_1S_BLOCK = 0x00u, /*!< Checks if an entire program flash or data flash logical block has been erased to the specified margin level */ + LDD_FLASH_READ_1S_SECTION = 0x01u, /*!< Checks if a section of program flash or data flash memory is erased to the specified read margin level */ + LDD_FLASH_WRITE_BYTE = 0x04u, /*!< Program byte */ + LDD_FLASH_WRITE_WORD = 0x05u, /*!< Program word */ + LDD_FLASH_WRITE_LONG_WORD = 0x06u, /*!< Program long word */ + LDD_FLASH_WRITE_PHRASE = 0x07u, /*!< Program phrase */ + LDD_FLASH_ERASE_FLASH_BLOCK = 0x08u, /*!< Erase flash memory block */ + LDD_FLASH_ERASE_SECTOR = 0x09u, /*!< Erase sector */ + LDD_FLASH_ERASE_ALL_FLASH_BLOCKS = 0x44u /*!< Erase all flash memory blocks */ +} LDD_FLASH_TCommand; + +/*! Type specifying possible FLASH component operation types */ +typedef enum { + LDD_FLASH_NO_OPERATION, /*!< No operation - initial state */ + LDD_FLASH_READ, /*!< Read operation */ + LDD_FLASH_WRITE, /*!< Write operation */ + LDD_FLASH_ERASE, /*!< Erase operation */ + LDD_FLASH_ERASE_BLOCK, /*!< Erase block operation */ + LDD_FLASH_VERIFY_ERASED_BLOCK /*!< Verify erased block operation */ +} LDD_FLASH_TOperationType; + +/*! Type specifying possible FLASH component operation states */ +typedef enum { + LDD_FLASH_FAILED = 0x00u, /*!< Operation has failed */ + LDD_FLASH_STOP = 0x01u, /*!< The operation has been stopped */ + LDD_FLASH_IDLE = 0x02u, /*!< No operation in progress */ + LDD_FLASH_STOP_REQ = 0x03u, /*!< The operation is in the STOP request mode */ + LDD_FLASH_START = 0x04u, /*!< Start of the operation, no operation steps have been done yet */ + LDD_FLASH_RUNNING = 0x05u /*!< Operation is in progress */ +} LDD_FLASH_TOperationStatus; + +typedef uint8_t LDD_FLASH_TErrorFlags; /*!< Type specifying FLASH component's error flags bit field */ + +typedef uint32_t LDD_FLASH_TAddress; /*!< Type specifying the Address parameter used by the FLASH component's methods */ + +typedef uint32_t LDD_FLASH_TDataSize; /*!< Type specifying the Size parameter used by the FLASH component's methods */ + +typedef uint16_t LDD_FLASH_TErasableUnitSize; /*!< Type specifying the Size output parameter of the GetErasableUnitSize method (pointer to a variable of this type is passed to the method) */ + +/*! Type specifying the FLASH component's rrror status information */ +typedef struct { + LDD_FLASH_TOperationType CurrentOperation; /*!< Current operation */ + LDD_FLASH_TCommand CurrentCommand; /*!< Last flash controller command */ + LDD_FLASH_TErrorFlags CurrentErrorFlags; /*!< Bitfield with error flags. See FLASH2.h for details */ + LDD_FLASH_TAddress CurrentAddress; /*!< Address of the flash memory location the error status is related to */ + LDD_TData *CurrentDataPtr; /*!< Pointer to current input data the error status is related to */ + LDD_FLASH_TDataSize CurrentDataSize; /*!< Size of the current input data to be programmed or erased in bytes */ +} LDD_FLASH_TErrorStatus; + +/* +** =================================================================== +** HSCMP device types and constants +** =================================================================== +*/ + +#define LDD_ANALOGCOMP_ON_COMPARE 0x01u /*!< OnCompare event mask */ + +/* Positive input pin masks */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_0_MASK 0x01U /*!< Mask for positive input pin 0 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_1_MASK 0x02U /*!< Mask for positive input pin 1 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_2_MASK 0x04U /*!< Mask for positive input pin 2 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_3_MASK 0x08U /*!< Mask for positive input pin 3 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_4_MASK 0x10U /*!< Mask for positive input pin 4 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_5_MASK 0x20U /*!< Mask for positive input pin 5 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_6_MASK 0x40U /*!< Mask for positive input pin 6 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_7_MASK 0x80U /*!< Mask for positive input pin 7 */ + +/* Negative input pin masks */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_0_MASK 0x0100U /*!< Mask for negative input pin 0 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_1_MASK 0x0200U /*!< Mask for negative input pin 1 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_2_MASK 0x0400U /*!< Mask for negative input pin 2 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_3_MASK 0x0800U /*!< Mask for negative input pin 3 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_4_MASK 0x1000U /*!< Mask for negative input pin 4 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_5_MASK 0x2000U /*!< Mask for negative input pin 5 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_6_MASK 0x4000U /*!< Mask for negative input pin 6 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_7_MASK 0x8000U /*!< Mask for negative input pin 7 */ + +/* Output pin masks */ +#define LDD_ANALOGCOMP_OUTPUT_PIN_MASK 0x00010000U /*!< Mask for output pin */ + +/* Window Sample pin masks */ +#define LDD_ANALOGCOMP_WINDOWSAMPLE_PIN_MASK 0x00020000UL + +/*! Type specifying comparator input number */ +typedef enum { + LDD_ANALOGCOMP_INPUT_0 = 0x00U, /*!< Analog input 0 selected */ + LDD_ANALOGCOMP_INPUT_1 = 0x01U, /*!< Analog input 1 selected */ + LDD_ANALOGCOMP_INPUT_2 = 0x02U, /*!< Analog input 2 selected */ + LDD_ANALOGCOMP_INPUT_3 = 0x03U, /*!< Analog input 3 selected */ + LDD_ANALOGCOMP_INPUT_4 = 0x04U, /*!< Analog input 4 selected */ + LDD_ANALOGCOMP_INPUT_5 = 0x05U, /*!< Analog input 5 selected */ + LDD_ANALOGCOMP_INPUT_6 = 0x06U, /*!< Analog input 6 selected */ + LDD_ANALOGCOMP_INPUT_7 = 0x07U, /*!< Analog input 7 selected */ + LDD_ANALOGCOMP_INPUT_DISABLED = 0x08U /*!< Analog input disabled */ +} LDD_AnalogComp_TComparatorInput; + +/*! Type specifying current comparator output status */ +typedef enum { + LDD_ANALOGCOMP_NO_EDGE = 0x00U, /*!< No edge detected on output */ + LDD_ANALOGCOMP_FALLING_EDGE = 0x02U, /*!< Falling edge detected on output */ + LDD_ANALOGCOMP_RISING_EDGE = 0x04U, /*!< Rising edge detected on output */ + LDD_ANALOGCOMP_BOTH_EDGES = 0x06U /*!< Both edges detected on output */ +} LDD_AnalogComp_TCompareStatus; + +/*! Type specifying requested comparator mode */ +typedef enum { + LDD_ANALOGCOMP_RISING_EDGE_MODE = 0x10U, /*!< Rising edge detection */ + LDD_ANALOGCOMP_FALLING_EDGE_MODE = 0x08U, /*!< Falling edge detection */ + LDD_ANALOGCOMP_BOTH_EDGES_MODE = 0x18U /*!< Both edges detection */ +} LDD_AnalogComp_TComparatorMode; + +typedef uint8_t LDD_AnalogComp_TOutputValue; /*!< Type specifying comparator output value */ + +/* +** =================================================================== +** SDHC component types and constants +** =================================================================== +*/ + +#define LDD_SDHC_CARD_DATA_WIDTH_1_BIT 0x01u /*!< Card supports 1 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_4_BIT 0x02u /*!< Card supports 4 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_8_BIT 0x04u /*!< Card supports 8 bit data bus */ +#define LDD_SDHC_CARD_BLOCK_READ 0x01u /*!< Card supports block reading */ +#define LDD_SDHC_CARD_BLOCK_WRITE 0x04u /*!< Card supports block writing */ +#define LDD_SDHC_CARD_ERASE 0x08u /*!< Card supports block erasion */ +#define LDD_SDHC_CARD_WRITE_PROTECTION 0x10u /*!< Card supports write protection */ +#define LDD_SDHC_CARD_IO 0x80u /*!< Card supports IO */ + +#define LDD_SDHC_CLK_PIN 0x01u /*!< SD clock pin mask */ +#define LDD_SDHC_CMD_PIN 0x02u /*!< SD command line pin mask */ +#define LDD_SDHC_DAT0_PIN 0x04u /*!< SD data line 0 pin mask */ +#define LDD_SDHC_DAT1_PIN 0x08u /*!< SD data line 1 pin mask */ +#define LDD_SDHC_DAT2_PIN 0x10u /*!< SD data line 2 pin mask */ +#define LDD_SDHC_DAT3_PIN 0x20u /*!< SD data line 3 pin mask */ +#define LDD_SDHC_DAT4_PIN 0x40u /*!< SD data line 4 pin mask */ +#define LDD_SDHC_DAT5_PIN 0x80u /*!< SD data line 5 pin mask */ +#define LDD_SDHC_DAT6_PIN 0x0100u /*!< SD data line 6 pin mask */ +#define LDD_SDHC_DAT7_PIN 0x0200u /*!< SD data line 7 pin mask */ +#define LDD_SDHC_CD_PIN 0x0400u /*!< SD card detection pin mask */ +#define LDD_SDHC_WP_PIN 0x0800u /*!< SD write protection pin mask */ +#define LDD_SDHC_LCTL_PIN 0x1000u /*!< SD LED control pin mask */ +#define LDD_SDHC_VS_PIN 0x2000u /*!< SD voltage control pin mask */ + +#define LDD_SDHC_ON_CARD_INSERTED 0x01u /*!< OnCardInserted event mask */ +#define LDD_SDHC_ON_CARD_REMOVED 0x02u /*!< OnCardRemoved event mask */ +#define LDD_SDHC_ON_FINISHED 0x04u /*!< OnFinished event mask */ + +/*! Card types */ +typedef enum { + LDD_SDHC_SD, /*!< Secure Digital memory card */ + LDD_SDHC_SDIO, /*!< Secure Digital IO card */ + LDD_SDHC_SDCOMBO, /*!< Combined Secure Digital memory and IO card */ + LDD_SDHC_MMC, /*!< MultiMediaCard memory card */ + LDD_SDHC_CE_ATA /*!< Consumer Electronics ATA card */ +} LDD_SDHC_TCardType; + +/*! Card access properties */ +typedef struct { + uint16_t MaxBlockLength; /*!< Max. transferable block length */ + bool MisalignBlock; /*!< Indicates if the data block can be spread over more than one physical block of the memory device */ + bool PartialBlock; /*!< Indicates whether partial block sizes can be used in block access */ +} LDD_SDHC_TCardAccess; + +/*! Card erasion properties */ +typedef struct { + uint16_t SectorSize; /*!< The size of an erasable unit */ + uint8_t Pattern; /*!< Memory content after erase */ +} LDD_SDHC_TCardErase; + +/*! Card write protection properties */ +typedef struct { + uint16_t GroupSize; /*!< The size of write protected group in number of erase groups */ + bool Permanent; /*!< Indicates whether card is permanently write protected (read-only) */ +} LDD_SDHC_TCardWriteProtect; + +/*! Card capabilities */ +typedef struct { + uint8_t DataWidths; /*!< Bit mask of supported data bus widths */ + uint8_t Operations; /*!< Bit mask of supported operations */ + bool HighSpeed; /*!< Indicates whether the card supports high clock configuration (SD bus clock frequency higher than about 25MHz) */ + bool HighCapacity; /*!< Indicates whether the card requires block addressing instead of byte addressing */ + bool LowVoltage; /*!< Indicates whether the card supports the host's low voltage range */ + LDD_SDHC_TCardAccess Read; /*!< Card data read access capabilities */ + LDD_SDHC_TCardAccess Write; /*!< Card data write access capabilities */ + LDD_SDHC_TCardErase Erase; /*!< Card data erasion capabilities */ + LDD_SDHC_TCardWriteProtect WriteProtect; /*!< Write protection properties */ +} LDD_SDHC_TCardCaps; + +/*! Card features description */ +typedef struct { + LDD_SDHC_TCardType Type; /*!< Card type */ + uint16_t BlockLength; /*!< Physical memory block length */ + uint32_t BlockCount; /*!< Number of physical memory blocks */ + LDD_SDHC_TCardCaps Caps; /*!< Card capabilities */ +} LDD_SDHC_TCardInfo; + +/*! Transfer operations */ +typedef enum { + LDD_SDHC_READ, /*!< Read operation */ + LDD_SDHC_WRITE /*!< Write operation */ +} LDD_SDHC_TTransferOperation; + +/*! Transfer buffer descriptor */ +typedef struct { + uint16_t Size; /*!< Buffer data size */ + uint8_t *DataPtr; /*!< Pointer to buffer data */ +} LDD_SDHC_TBufferDesc; + +/*! Voltage options */ +typedef enum { + LDD_SDHC_LOW_VOLTAGE, /*!< Low voltage */ + LDD_SDHC_HIGH_VOLTAGE /*!< High voltage */ +} LDD_SDHC_TVoltage; + +/*! Write protection types */ +typedef enum { + LDD_SDHC_GROUP, /*!< Write protection by groups */ + LDD_SDHC_CARD /*!< Whole card write protection */ +} LDD_SDHC_TWriteProtectType; + +/*! Component states */ +typedef enum { + LDD_SDHC_DISABLED, /*!< Disabled */ + LDD_SDHC_RESET, /*!< Resetting card */ + LDD_SDHC_IDLE, /*!< Idling */ + LDD_SDHC_VOLTAGE_VALIDATION, /*!< Validating voltage */ + LDD_SDHC_CARD_REGISTRATION, /*!< Registrating card */ + LDD_SDHC_CARD_SELECTION, /*!< Selecting card */ + LDD_SDHC_CARD_INFO_RETRIEVAL, /*!< Retrieving card info */ + LDD_SDHC_TRANSFER, /*!< Transferring data */ + LDD_SDHC_ERASION, /*!< Erasing blocks */ + LDD_SDHC_IO_REG_TRANSFER, /*!< Transferring IO registers */ + LDD_SDHC_DATA_WIDTH_SELECTION, /*!< Selecting data width */ + LDD_SDHC_BUS_CLOCK_SELECTION, /*!< Selecting bus clock */ + LDD_SDHC_WRITE_PROTECTION_SETUP, /*!< Setting up write protection */ + LDD_SDHC_WRITE_PROTECTION_RETRIEVAL /*!< Retrieving write protection configuration */ +} LDD_SDHC_TStatus; + +/*! Operation completion error codes */ +typedef enum { + LDD_SDHC_ERR_OK, /*!< No error */ + LDD_SDHC_ERR_DMA, /*!< DMA or block size error */ + LDD_SDHC_ERR_NOT_SUPPORTED, /*!< Initiated operation is not supported by the card (supported operations are contained in the card information structure) */ + LDD_SDHC_ERR_TIMEOUT, /*!< Command or data timeout */ + LDD_SDHC_ERR_COMMAND_CRC, /*!< Command CRC check failed */ + LDD_SDHC_ERR_DATA_CRC, /*!< Data CRC check failed */ + LDD_SDHC_ERR_ADDRESS_OUT_OF_RANGE, /*!< The card address is beyond the card capacity */ + LDD_SDHC_ERR_ADDRESS_MISALIGN, /*!< The card address does not align with physical blocks of the card */ + LDD_SDHC_ERR_BLOCK_LEN_ERROR, /*!< Block length exceeds the maximum value for the card */ + LDD_SDHC_ERR_WP_VIOLATION, /*!< Attempt to program a write protected block */ + LDD_SDHC_ERR_CARD_IS_LOCKED, /*!< The card is locked by the host */ + LDD_SDHC_ERR_WP_ERASE_SKIP, /*!< Only partial address space was erased due to existing write protected blocks */ + LDD_SDHC_ERR_INTERNAL_FAILURE, /*!< Internal component error */ + LDD_SDHC_ERR_CARD_FAILURE /*!< The card was unable to complete the operation */ +} LDD_SDHC_TError; + +/* +** =================================================================== +** DMA device types and constants +** =================================================================== +*/ + +#define LDD_DMA_ON_COMPLETE 0x01U /*!< OnTransferComplete event mask. */ +#define LDD_DMA_ON_ERROR 0x02U /*!< OnError event mask. */ + +#define LDD_DMA_UNKNOWN_ERROR 0x80000000U /*!< Unknown error. */ +#define LDD_DMA_CHANNEL_PRIORITY_ERROR 0x4000U /*!< Channel priority error. */ +#define LDD_DMA_SOURCE_ADDRESS_ERROR 0x80U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_SOURCE_OFFSET_ERROR 0x40U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_ADDRESS_ERROR 0x20U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_OFFSET_ERROR 0x10U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_COUNT_ERROR 0x08U /*!< Byte count inconsistency with transfer sizes or transfer count error. */ +#define LDD_DMA_SCATTER_GATHER_ERROR 0x04U /*!< Scatter/gather configuration error. */ +#define LDD_DMA_SOURCE_BUS_ERROR 0x02U /*!< Bus error on a source read. */ +#define LDD_DMA_DESTINATION_BUS_ERROR 0x01U /*!< Bus error on a destination write. */ + +#define LDD_DMA_CHANNEL_0_MASK 0x01UL /*!< DMA channel 0 mask. */ +#define LDD_DMA_CHANNEL_1_MASK 0x02UL /*!< DMA channel 1 mask. */ +#define LDD_DMA_CHANNEL_2_MASK 0x04UL /*!< DMA channel 2 mask. */ +#define LDD_DMA_CHANNEL_3_MASK 0x08UL /*!< DMA channel 3 mask. */ +#define LDD_DMA_CHANNEL_4_MASK 0x10UL /*!< DMA channel 4 mask. */ +#define LDD_DMA_CHANNEL_5_MASK 0x20UL /*!< DMA channel 5 mask. */ +#define LDD_DMA_CHANNEL_6_MASK 0x40UL /*!< DMA channel 6 mask. */ +#define LDD_DMA_CHANNEL_7_MASK 0x80UL /*!< DMA channel 7 mask. */ +#define LDD_DMA_CHANNEL_8_MASK 0x0100UL /*!< DMA channel 8 mask. */ +#define LDD_DMA_CHANNEL_9_MASK 0x0200UL /*!< DMA channel 9 mask. */ +#define LDD_DMA_CHANNEL_10_MASK 0x0400UL /*!< DMA channel 10 mask. */ +#define LDD_DMA_CHANNEL_11_MASK 0x0800UL /*!< DMA channel 11 mask. */ +#define LDD_DMA_CHANNEL_12_MASK 0x1000UL /*!< DMA channel 12 mask. */ +#define LDD_DMA_CHANNEL_13_MASK 0x2000UL /*!< DMA channel 13 mask. */ +#define LDD_DMA_CHANNEL_14_MASK 0x4000UL /*!< DMA channel 14 mask. */ +#define LDD_DMA_CHANNEL_15_MASK 0x8000UL /*!< DMA channel 15 mask. */ +#define LDD_DMA_CHANNEL_16_MASK 0x00010000UL /*!< DMA channel 16 mask. */ +#define LDD_DMA_CHANNEL_17_MASK 0x00020000UL /*!< DMA channel 17 mask. */ +#define LDD_DMA_CHANNEL_18_MASK 0x00040000UL /*!< DMA channel 18 mask. */ +#define LDD_DMA_CHANNEL_19_MASK 0x00080000UL /*!< DMA channel 19 mask. */ +#define LDD_DMA_CHANNEL_20_MASK 0x00100000UL /*!< DMA channel 21 mask. */ +#define LDD_DMA_CHANNEL_21_MASK 0x00200000UL /*!< DMA channel 22 mask. */ +#define LDD_DMA_CHANNEL_22_MASK 0x00400000UL /*!< DMA channel 23 mask. */ +#define LDD_DMA_CHANNEL_23_MASK 0x00800000UL /*!< DMA channel 24 mask. */ +#define LDD_DMA_CHANNEL_24_MASK 0x01000000UL /*!< DMA channel 25 mask. */ +#define LDD_DMA_CHANNEL_25_MASK 0x02000000UL /*!< DMA channel 26 mask. */ +#define LDD_DMA_CHANNEL_26_MASK 0x04000000UL /*!< DMA channel 27 mask. */ +#define LDD_DMA_CHANNEL_27_MASK 0x08000000UL /*!< DMA channel 28 mask. */ +#define LDD_DMA_CHANNEL_28_MASK 0x10000000UL /*!< DMA channel 29 mask. */ +#define LDD_DMA_CHANNEL_29_MASK 0x20000000UL /*!< DMA channel 30 mask. */ +#define LDD_DMA_CHANNEL_30_MASK 0x40000000UL /*!< DMA channel 31 mask. */ +#define LDD_DMA_CHANNEL_31_MASK 0x80000000UL /*!< DMA channel 32 mask. */ + +/* Action executed after request and transfer service completes */ +#define LDD_DMA_NO_ACTION 0x00U /*!< No action performed after request serviced. */ +#define LDD_DMA_DESTINATION_ADDRESS_ADJUSTMENT 0x01U /*!< Destination address adjustment after request serviced. */ +#define LDD_DMA_SOURCE_ADDRESS_ADJUSTMENT 0x02U /*!< Source address adjustment after request serviced. */ +#define LDD_DMA_ADDRESS_ADJUSTMENT 0x01U /*!< Address adjustment after transfer completed. */ +#define LDD_DMA_SCATTER_GATHER 0x02U /*!< Scatter/gather performed after transfer completed. */ + +typedef void LDD_DMA_TData; +typedef uint8_t LDD_DMA_TTransactionSize; /* Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TTransactionCount; +typedef uint32_t LDD_DMA_TRequestCount; +typedef uint32_t LDD_DMA_TTransferDataSize; + +typedef uint32_t LDD_DMA_TAddress; /*!< Type specifying the address parameter used by the DMA component's methods. */ +typedef int32_t LDD_DMA_TAddressOffset; /*!< Type specifying the address signed offset parameter used by the DMA component's methods. */ +typedef uint32_t LDD_DMA_TByteCount; /*!< Type specifying the byte count/minor loop count parameter used by the DMA component's methods. */ +typedef uint8_t LDD_DMA_TTransferSize; /*!< Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TModuloSize; /*!< Type specifying the modulo size parameter used by the DMA component's methods. */ + /*!< This value power of two represents size of used circular buffer (0U - buffer disabled). See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TTriggerSource; /*!< Type specifying the trigger source signal number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TChannelNumber; /*!< Type specifying the DMA channel number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TRecordNumber; /*!< Type specifying the DMA descriptor record number. */ +typedef uint32_t LDD_DMA_TChannelMask; /*!< Type specifying the DMA channel mask. For possible values see channel mask constants. */ +typedef uint8_t LDD_DMA_TChannelPriority; /*!< Type specifying the DMA channel priority number. See the MCU manual for detail description of allowed values. */ +typedef uint16_t LDD_DMA_TOuterLoopCount; /*!< Type specifying the transfer outer/major loop count. */ +typedef uint8_t LDD_DMA_TAfterRequest; /*!< Type specifying the operation executed after request service is completed. */ +typedef uint8_t LDD_DMA_TAfterTransfer; /*!< Type specifying the operation executed after transfer service is completed. */ +typedef uint8_t LDD_DMA_TBandwidthControl; /*!< Type specifying the bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TErrorFlags; /*!< DMA controller error flags. See the DMA_LDD component's header file for detail description of allowed values. */ + +/*! Type specifying a DMA channel status. */ +typedef enum { + LDD_DMA_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_DONE, /*!< Transfer is completed, waiting to start of next transfer. */ + LDD_DMA_ERROR /*!< Error detected. */ +} LDD_DMA_TChannelStatus; + +/*! Type specifying a DMA transfer state. */ +typedef enum { + LDD_DMA_TRANSFER_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_TRANSFER_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_TRANSFER_ERROR /*!< Error detected. */ +} LDD_DMA_TTransferState; + +/*! Type specifying the DMA transfer mode. */ +typedef enum { + LDD_DMA_CYCLE_STEAL_TRANSFERS, /*!< Only single read/write transfer is done per one service request. */ + LDD_DMA_SINGLE_TRANSFER, /*!< Transfer of all bytes defined by Data size is done after single service request. */ + LDD_DMA_NESTED_TRANSFERS /*!< Sequence of transfers triggered by service requests. One request transfers number of bytes defined by Byte count value. */ +} LDD_DMA_TTransferMode; + +/*! Type specifying the DMA trigger source type. */ +typedef enum { + LDD_DMA_SW_TRIGGER, /*!< Explicit software trigger. */ + LDD_DMA_HW_TRIGGER, /*!< Peripheral device trigger. */ + LDD_DMA_ALWAYS_ENABLED_TRIGGER /*!< Always enabled trigger. */ +} LDD_DMA_TTriggerType; + +/*! Type specifying the DMA error information structure. */ +typedef struct { + LDD_DMA_TChannelNumber ChannelNumber; /*!< Last error recorded channel number. */ + LDD_DMA_TErrorFlags ErrorFlags; /*!< Channel error flags. */ +} LDD_DMA_TError; + +/*! Type specifying the DMA Transfer descriptor information structure. */ +typedef struct { + LDD_TUserData *UserDataPtr; /*!< User device data structure pointer to be returned by the DMA_LDD component's ISR to the dynamic callback of this transfer descriptor. */ + LDD_DMA_TAddress SourceAddress; /*!< Address of a DMA transfer source data. */ + LDD_DMA_TAddressOffset SourceAddressOffset; /*!< Offset to be added to the source address after each elemental read operation. */ + LDD_DMA_TTransferSize SourceTransferSize; /*!< Source data transfer size (size of a elemental read operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize SourceModuloSize; /*!< Source address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TAddress DestinationAddress; /*!< Address of a DMA transfer destination. */ + LDD_DMA_TAddressOffset DestinationAddressOffset; /*!< Offset to be added to the destination address after each elemental write operation. */ + LDD_DMA_TTransferSize DestinationTransferSize; /*!< Destination data transfer size (size of a elemental write operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize DestinationModuloSize; /*!< Destination address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TTransferMode TransferMode; /*!< Selects DMA transfer mode. For the description of allowed values see the LDD_DMA_TTransferMode type declaration. */ + LDD_DMA_TByteCount ByteCount; /*!< Size of data in bytes to be transferred in single transfer. */ + LDD_DMA_TOuterLoopCount OuterLoopCount; /*!< Number of the outer loop iteration in the Nested operation mode, otherwise should have value of one. */ + bool InnerLoopChannelLink; /*!< TRUE - Inner loop channel linking enabled (if the nested operation is used, then this item enables the minor (inner) loop channel linking). */ + LDD_DMA_TChannelNumber InnerLoopLinkedChannel; /*!< Linked DMA channel number (used only if the InnerLoopChannelLink item is set TRUE) */ + bool OuterLoopChannelLink; /*!< TRUE - Outer (major) loop channel linking is enabled. Enables channel linking after transfer completes. */ + LDD_DMA_TChannelNumber OuterLoopLinkedChannel; /*!< Outer (major) loop linked DMA channel number (used only if the OuterLoopChannelLink item is set TRUE). */ + LDD_DMA_TAfterRequest AfterRequestComplete; /*!< Type of an action after the elemental read/write operation is done. For the description of allowed values see the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAddressOffset AddressOffset; /*!< Address offset value. Address specified in AfterRequestComplete item is adjusted by stored value. See the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAfterTransfer AfterTransferComplete; /*!< Type of an action executed after the last transfer operation is done. For the description of allowed values see the LDD_DMA_TAfterTransfer type declaration. */ + LDD_DMA_TAddressOffset SourceAddressAdjustment; /*!< Source address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddressOffset DestinationAddressAdjustment; /*!< Destination address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddress ScatterGatherAddress; /*!< Scatter / gather address. Used only if the AfterTransferComplete item is set to LDD_DMA_SCATTER_GATHER. */ + LDD_DMA_TBandwidthControl BandwidthControl; /*!< DMA channel bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ + bool ChannelAutoSelection; /*!< TRUE - DMA channel autoselection engine is used. FALSE - DMA fixed channel is used. */ + LDD_DMA_TChannelNumber ChannelNumber; /*!< If ChannelAutoSelection is FALSE this item contains fixed channel number. If ChannelAutoSelection is TRUE then after allocation this item is filled by autoselected channel number. */ + LDD_DMA_TTriggerType TriggerType; /*!< DMA transfer trigger type. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + LDD_DMA_TTriggerSource TriggerSource; /*!< Trigger source number. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + bool PeriodicTrigger; /*!< TRUE - periodic trigger is required, FALSE - periodic trigger is not required. */ + bool DisableAfterRequest; /*!< TRUE - DMA transfer request is automatically disabled after transfer complete. */ + bool Interrupts; /*!< TRUE - interrupts are requested. */ + bool OnComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnHalfComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnError; /*!< TRUE - event is enabled during initialization. */ + void (*OnCompleteEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnComplete event, NULL if event is not used. */ + void (*OnErrorEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnError event, NULL if event is not used. */ + bool ChannelEnabled; /*!< TRUE - DMA channel is allocated and used by DMATransfer component. */ +} LDD_DMA_TTransferDescriptor; + +typedef LDD_DMA_TTransferDescriptor *LDD_DMA_TTransferDescriptorPtr; /*!< Type specifying address of the DMA Transfer descriptor structure. */ + +/* +** =================================================================== +** SPI device types and constants - SPIMaster_LDD +** =================================================================== +*/ + +#define LDD_SPIMASTER_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPIMASTER_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPIMASTER_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPIMASTER_CS_0_PIN 0x08U /*!< Chip select 0 pin mask */ +#define LDD_SPIMASTER_CS_1_PIN 0x10U /*!< Chip select 1 pin mask */ +#define LDD_SPIMASTER_CS_2_PIN 0x20U /*!< Chip select 2 pin mask */ +#define LDD_SPIMASTER_CS_3_PIN 0x40U /*!< Chip select 3 pin mask */ +#define LDD_SPIMASTER_CS_4_PIN 0x80U /*!< Chip select 4 pin mask */ +#define LDD_SPIMASTER_CS_5_PIN 0x0100U /*!< Chip select 5 pin mask */ +#define LDD_SPIMASTER_CS_6_PIN 0x0200U /*!< Chip select 6 pin mask */ +#define LDD_SPIMASTER_CS_7_PIN 0x0400U /*!< Chip select 7 pin mask */ +#define LDD_SPIMASTER_CSS_PIN 0x0800U /*!< Chip select strobe pin mask */ + +#define LDD_SPIMASTER_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPIMASTER_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPIMASTER_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPIMASTER_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPIMASTER_PARITY_ERROR 0x02U /*!< Parity error */ +#define LDD_SPIMASTER_RX_DMA_ERROR 0x04U /*!< Receive DMA channel error */ +#define LDD_SPIMASTER_TX_DMA_ERROR 0x08U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPIMASTER_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ +} LDD_SPIMASTER_TStats; + +/* +** =================================================================== +** SPI device types and constants - SPISlave_LDD +** =================================================================== +*/ + +#define LDD_SPISLAVE_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPISLAVE_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPISLAVE_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPISLAVE_SS_PIN 0x08U /*!< Slave select pin mask */ + +#define LDD_SPISLAVE_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPISLAVE_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPISLAVE_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPISLAVE_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPISLAVE_TX_UNDERFLOW 0x02U /*!< Transmitter underflow */ +#define LDD_SPISLAVE_PARITY_ERROR 0x04U /*!< Parity error */ +#define LDD_SPISLAVE_RX_DMA_ERROR 0x08U /*!< Receive DMA channel error */ +#define LDD_SPISLAVE_TX_DMA_ERROR 0x10U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPISLAVE_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ +} LDD_SPISLAVE_TStats; + +/* +** =================================================================== +** I2S device types and constants +** =================================================================== +*/ + +#define LDD_SSI_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SSI_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SSI_RX_CLK_PIN 0x04U /*!< Rx clock pin mask */ +#define LDD_SSI_TX_CLK_PIN 0x08U /*!< Tx clock pin mask */ +#define LDD_SSI_RX_FS_PIN 0x10U /*!< Rx frame sync pin mask */ +#define LDD_SSI_TX_FS_PIN 0x20U /*!< Tx frame sync pin mask */ +#define LDD_SSI_MCLK_PIN 0x40U /*!< Master clock pin mask */ +#define LDD_SSI_INPUT_PIN_CHANNEL_0 0x80U /*!< Input pin mask for data channel 0 */ +#define LDD_SSI_INPUT_PIN_CHANNEL_1 0x0100U /*!< Input pin mask for data channel 1 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_0 0x0200U /*!< Output pin mask for data channel 0 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_1 0x0400U /*!< Output pin mask for data channel 1 */ + +#define LDD_SSI_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SSI_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SSI_ON_ERROR 0x04u /*!< OnError event mask */ +#define LDD_SSI_ON_BLOCK_RECEIVED_1 0x08u /*!< OnBlockReceived event mask for second channel */ +#define LDD_SSI_ON_BLOCK_SENT_1 0x10u /*!< OnBlockSent event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_FRAME_SYNC 0x20u /*!< OnReceiveFrameSync event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_FRAME_SYNC 0x40u /*!< OnTransmitFrameSync event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_LAST_SLOT 0x80u /*!< OnReceiveLastSlot event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_LAST_SLOT 0x0100u /*!< OnTransmitLastSlot event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_COMPLETE 0x0200u /*!< OnReceiveComplete event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_COMPLETE 0x0400u /*!< OnTransmitComplete event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ + +#define LDD_SSI_RECEIVER 0x01U /*!< Receive section of the device. */ +#define LDD_SSI_TRANSMITTER 0x02U /*!< Transmit section of the device. */ + +#define LDD_SSI_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SSI_RX_OVERFLOW_1 0x02U /*!< Receiver overflow 1 */ +#define LDD_SSI_RX_SYNC_ERROR 0x04U /*!< Receiver frame sync error */ +#define LDD_SSI_RX_DMA_ERROR 0x08U /*!< Receiver DMA error */ + +#define LDD_SSI_TX_UNDERFLOW 0x10U /*!< Transmitter underflow */ +#define LDD_SSI_TX_UNDERFLOW_1 0x20U /*!< Transmitter underflow 1 */ +#define LDD_SSI_TX_SYNC_ERROR 0x40U /*!< Transmitter frame sync error */ +#define LDD_SSI_TX_DMA_ERROR 0x80U /*!< Transmitter DMA error */ + +#define LDD_SSI_RX_FRAME_COMPLETE 0x01U /*!< Receive frame is finished after disabling transfer */ +#define LDD_SSI_TX_FRAME_COMPLETE 0x02U /*!< Transmit frame is finished after disabling transfer */ +#define LDD_SSI_RX_FRAME_SYNC 0x04U /*!< Receiver frame sync */ +#define LDD_SSI_TX_FRAME_SYNC 0x08U /*!< Transmit frame sync */ +#define LDD_SSI_RX_LAST_SLOT 0x10U /*!< Receive last time slot */ +#define LDD_SSI_TX_LAST_SLOT 0x20U /*!< Transmit last time slot */ +#define LDD_SSI_AC97_TAG 0x40U /*!< AC97 tag updated */ +#define LDD_SSI_AC97_COMMAND_ADDRESS 0x80U /*!< AC97 command address updated */ +#define LDD_SSI_AC97_COMMAND_DATA 0x0100U /*!< AC97 command data updated */ + +typedef uint8_t LDD_SSI_TSectionMask; /*!< Device section type */ + +typedef uint32_t LDD_SSI_TError; /*!< Communication error type */ + +typedef uint32_t LDD_SSI_TComStatus; /*!< Communication status type */ + +/*! Group of pointers to data blocks. */ +typedef struct { + LDD_TData *Channel0Ptr; /*!< Pointer to data block to send/received via data channel 0 */ + LDD_TData *Channel1Ptr; /*!< Pointer to data block to send/received via data channel 1 */ +} LDD_SSI_TDataBlocks; + +/*! Command type */ +typedef enum { + LDD_SSI_READ_COMMAND = 0x08u, + LDD_SSI_WRITE_COMMAND = 0x10u +} LDD_SSI_TAC97CommandType; + +/*! AC97 command */ +typedef struct { + LDD_SSI_TAC97CommandType Type; /*!< Command type */ + uint32_t Address; /*!< Command address */ + uint32_t Data; /*!< Command data */ +} LDD_SSI_TAC97Command; + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ + uint32_t RxChars1; /*!< Number of received characters for second channel */ + uint32_t TxChars1; /*!< Number of transmitted characters for second channel */ + uint32_t RxOverruns1; /*!< Number of receiver overruns, which have occured for second channel */ + uint32_t TxUnderruns1; /*!< Number of transmitter underruns, which have occured for second channel */ +} LDD_SSI_TStats; + +/* +** =================================================================== +** RTC device types and constants +** =================================================================== +*/ + +#define LDD_RTC_ON_SECOND 0x10u /*!< OnSecond event mask */ +#define LDD_RTC_ON_MONOTONIC_OVERFLOW 0x08u /*!< OnMonotonicCounter event mask */ +#define LDD_RTC_ON_ALARM 0x04u /*!< OnAlarm event mask */ +#define LDD_RTC_ON_TIME_OVERFLOW 0x02u /*!< OnTimeOverflow event mask */ +#define LDD_RTC_ON_TIME_INVALID 0x01u /*!< OnTimeInvalid event mask */ +#define LDD_RTC_ON_STOPWATCH 0x0100u /*!< OnStopwatch event mask */ + +/*! Structure used for time operation */ +typedef struct { + uint32_t Second; /*!< seconds (0 - 59) */ + uint32_t Minute; /*!< minutes (0 - 59) */ + uint32_t Hour; /*!< hours (0 - 23) */ + uint32_t DayOfWeek; /*!< day of week (0-Sunday, .. 6-Saturday) */ + uint32_t Day; /*!< day (1 - 31) */ + uint32_t Month; /*!< month (1 - 12) */ + uint32_t Year; /*!< year */ +} LDD_RTC_TTime; + + + +/* +** =================================================================== +** CRC device types and constants +** =================================================================== +*/ + +#define LDD_CRC_16_SEED_LOW 0x00U /*!< CRC 16bit seed low */ +#define LDD_CRC_16_POLY_LOW 0x8005U /*!< CRC 16bit poly low */ +#define LDD_CRC_32_SEED_LOW 0xFFFFU /*!< CRC 32bit seed low */ +#define LDD_CRC_32_SEED_HIGH 0xFFFFU /*!< CRC 32bit seed high */ +#define LDD_CRC_32_POLY_LOW 0x1DB7U /*!< CRC 32bit poly low */ +#define LDD_CRC_32_POLY_HIGH 0x04C1U /*!< CRC 32bit poly high */ +#define LDD_CRC_CCITT_SEED_LOW 0xFFFFU /*!< CRC CCITT seed low */ +#define LDD_CRC_CCITT_POLY_LOW 0x1021U /*!< CRC CCITT poly low */ +#define LDD_CRC_MODBUS_16_SEED_LOW 0xFFFFU /*!< CRC MODBUS16 seed low */ +#define LDD_CRC_MODBUS_16_POLY_LOW 0x8005U /*!< CRC MODBUS16 poly low */ +#define LDD_CRC_KERMIT_SEED_LOW 0x00U /*!< CRC KERMIT seed low */ +#define LDD_CRC_KERMIT_POLY_LOW 0x1021U /*!< CRC KERMIT poly low */ +#define LDD_CRC_DNP_SEED_LOW 0x00U /*!< CRC DNP seed low */ +#define LDD_CRC_DNP_POLY_LOW 0x3D65U /*!< CRC DNP poly low */ + +/*! Transpose type */ +typedef enum { + LDD_CRC_NO_TRANSPOSE = 0, /*!< No transposition */ + LDD_CRC_BITS = 1, /*!< Bits are transposed */ + LDD_CRC_BITS_AND_BYTES = 2, /*!< Bits and bytes are transposed */ + LDD_CRC_BYTES = 3 /*!< Bytes are transposed */ +} LDD_CRC_TTransposeType; + +/*! CRC standard */ +typedef enum { + LDD_CRC_16, /*!< CRC16 standard */ + LDD_CRC_CCITT, /*!< CCITT standard */ + LDD_CRC_MODBUS_16, /*!< MODBUS16 standard */ + LDD_CRC_KERMIT, /*!< KERMIT standard */ + LDD_CRC_DNP, /*!< DNP standard */ + LDD_CRC_32, /*!< CRC32 standard */ + LDD_CRC_USER /*!< User defined type */ +} LDD_CRC_TCRCStandard; + +/*! User CRC standard */ +typedef struct { + bool Width32bit; /*!< 32bit CRC? */ + bool ResultXORed; /*!< Result XORed? */ + uint16_t SeedLow; /*!< Seed low value */ + uint16_t SeedHigh; /*!< Seed high value */ + uint16_t PolyLow; /*!< Poly low value */ + uint16_t PolyHigh; /*!< Poly high value */ + LDD_CRC_TTransposeType InputTransposeMode; /*!< Input transpose type */ + LDD_CRC_TTransposeType OutputTransposeMode; /*!< Output transpose type */ +} LDD_CRC_TUserCRCStandard; + +/* +** =================================================================== +** RNG device types and constants +** =================================================================== +*/ + + +#define LDD_RNG_LFSR_ERROR 0x01U /*!< Linear feedback shift register error */ +#define LDD_RNG_OSCILLATOR_ERROR 0x02U /*!< Oscillator error */ +#define LDD_RNG_SELF_TEST_ERROR 0x04U /*!< Self test error */ +#define LDD_RNG_STATISTICAL_ERROR 0x08U /*!< LStatistical test error */ +#define LDD_RNG_FIFO_UNDERFLOW_ERROR 0x10U /*!< FIFO underflow error */ + +#define LDD_RNG_SELF_TETS_RESEED_ERROR 0x00200000U /*!< Reseed self test fail */ +#define LDD_RNG_SELF_TEST_PRNG_ERROR 0x00400000U /*!< PRNG self test fail */ +#define LDD_RNG_SELF_TEST_TRNG_ERROR 0x00800000U /*!< TRNG self test fail */ +#define LDD_RNG_MONOBIT_TEST_ERROR 0x01000000U /*!< Monobit test fail */ +#define LDD_RNG_LENGTH_1_RUN_TEST_ERROR 0x02000000U /*!< Length 1 run test fail */ +#define LDD_RNG_LENGTH_2_RUN_TEST_ERROR 0x04000000U /*!< Length 2 run test fail */ +#define LDD_RNG_LENGTH_3_RUN_TEST_ERROR 0x08000000U /*!< Length 3 run test fail */ +#define LDD_RNG_LENGTH_4_RUN_TEST_ERROR 0x10000000U /*!< Length 4 run test fail */ +#define LDD_RNG_LENGTH_5_RUN_TEST_ERROR 0x20000000U /*!< Length 5 run test fail */ +#define LDD_RNG_LENGTH_6_RUN_TEST_ERROR 0x40000000U /*!< Length 6 run test fail */ +#define LDD_RNG_LONG_RUN_TEST_ERROR 0x80000000U /*!< Long run test fail */ + +#define LDD_RNG_ON_SEED_GENERATION_DONE 0x01U /*!< OnSeedGenerationDone event mask */ +#define LDD_RNG_ON_SELF_TEST_DONE 0x02U /*!< OnSelfTestDone event mask */ +#define LDD_RNG_ON_ERROR_LFSR 0x04U /*!< OnErrorLFSR event mask */ +#define LDD_RNG_ON_OSC_ERROR 0x08U /*!< OnOscError event mask */ +#define LDD_RNG_ON_SELF_TEST_ERROR 0x10U /*!< OnSelfTestError event mask */ +#define LDD_RNG_ON_STATISTICAL_ERROR 0x20U /*!< OnStatisticalError event mask */ +#define LDD_RNG_ON_FIFO_UNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ +#define LDD_RNG_ON_FIFOUNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ + +#define LDD_RNG_STATUS_ERROR 0xFFFFU /*!< Error in RNG module flag */ +#define LDD_RNG_STATUS_NEW_SEED_DONE 0x40U /*!< New seed done flag */ +#define LDD_RNG_STATUS_SEED_DONE 0x20U /*!< Seed done flag */ +#define LDD_RNG_STATUS_SELF_TEST_DONE 0x10U /*!< Self test done flag */ +#define LDD_RNG_STATUS_RESEED_NEEDED 0x08U /*!< Reseed needed flag */ +#define LDD_RNG_STATUS_SLEEP 0x04U /*!< RNG in sleep mode */ +#define LDD_RNG_STATUS_BUSY 0x02U /*!< RNG busy flag */ + + +/* +** =================================================================== +** RNGA device types and constants +** =================================================================== +*/ + +#define LDD_RNG_ON_ERROR 0x01U /*!< OnError event mask */ + +#define LDD_RNG_STATUS_SECURITY_VIOLATION 0x01U /*!< Security violation occured */ +#define LDD_RNG_STATUS_LAST_READ_UNDERFLOW 0x02U /*!< Last read from RNGA caused underflow error */ +#define LDD_RNG_STATUS_OUT_REG_UNDERFLOW 0x04U /*!< The RNGA Output Register has been read while empty since last read of the RNGA Status Register. */ +#define LDD_RNG_STATUS_ERR_INT_PENDING 0x08U /*!< Error interrupt pending */ +#define LDD_RNG_STATUS_SLEEP_MODE 0x10U /*!< Sleep mode enabled */ + +/*! RNGA sleep mode */ +typedef enum { + LDD_RNG_SLEEP_ENABLED, /*!< RNGA is in sleep mode */ + LDD_RNG_SLEEP_DISABLED /*!< RNGA is running */ +} LDD_RNG_TSleepMode; + +/* +** =================================================================== +** DryIce device types and constants +** =================================================================== +*/ + +#define LDD_DRY_ON_TAMPER_DETECTED 0x01U /*!< OnTamperDetected event mask */ + +/* Tamper flags */ +#define LDD_DRY_TIME_OVERFLOW 0x04U /*!< RTC time overflow has occurred. */ +#define LDD_DRY_MONOTONIC_OVERFLOW 0x08U /*!< RTC monotonic overflow has occurred. */ +#define LDD_DRY_VOLTAGE_TAMPER 0x10U /*!< VBAT voltage is outside of the valid range. */ +#define LDD_DRY_CLOCK_TAMPER 0x20U /*!< The 32.768 kHz clock source is outside the valid range. */ +#define LDD_DRY_TEMPERATURE_TAMPER 0x40U /*!< The junction temperature is outside of specification. */ +#define LDD_DRY_SECURITY_TAMPER 0x80U /*!< The (optional) security module asserted its tamper detect. */ +#define LDD_DRY_FLASH_SECURITY 0x0100U /*!< The flash security is disabled. */ +#define LDD_DRY_TEST_MODE 0x0200U /*!< Any test mode has been entered. */ +/* Tamper flags indicating that the pin does not equal its expected value and was not filtered by the glitch filter (if enabled). */ +#define LDD_DRY_TAMPER_PIN_0 0x00010000U /*!< Mismatch on tamper pin 0. */ +#define LDD_DRY_TAMPER_PIN_1 0x00020000U /*!< Mismatch on tamper pin 1. */ +#define LDD_DRY_TAMPER_PIN_2 0x00040000U /*!< Mismatch on tamper pin 2. */ +#define LDD_DRY_TAMPER_PIN_3 0x00080000U /*!< Mismatch on tamper pin 3. */ +#define LDD_DRY_TAMPER_PIN_4 0x00100000U /*!< Mismatch on tamper pin 4. */ +#define LDD_DRY_TAMPER_PIN_5 0x00200000U /*!< Mismatch on tamper pin 5. */ +#define LDD_DRY_TAMPER_PIN_6 0x00400000U /*!< Mismatch on tamper pin 6. */ +#define LDD_DRY_TAMPER_PIN_7 0x00800000U /*!< Mismatch on tamper pin 7. */ + +#define LDD_DRY_SECURE_KEY_WORD_0 0x01U /*!< Secure key word 0 mask */ +#define LDD_DRY_SECURE_KEY_WORD_1 0x02U /*!< Secure key word 1 mask */ +#define LDD_DRY_SECURE_KEY_WORD_2 0x04U /*!< Secure key word 2 mask */ +#define LDD_DRY_SECURE_KEY_WORD_3 0x08U /*!< Secure key word 3 mask */ +#define LDD_DRY_SECURE_KEY_WORD_4 0x10U /*!< Secure key word 4 mask */ +#define LDD_DRY_SECURE_KEY_WORD_5 0x20U /*!< Secure key word 5 mask */ +#define LDD_DRY_SECURE_KEY_WORD_6 0x40U /*!< Secure key word 6 mask */ +#define LDD_DRY_SECURE_KEY_WORD_7 0x80U /*!< Secure key word 7 mask */ + +/* +** =================================================================== +** NFC device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_NFC_ON_CMD_ERROR 0x01U /*!< OnCmdError event mask */ +#define LDD_NFC_ON_CMD_DONE 0x02U /*!< OnCmdDone event mask */ + +/* Pins' masks */ +#define LDD_NFC_CE0_PIN 0x01U /*!< CE0 pin mask */ +#define LDD_NFC_RB0_PIN 0x02U /*!< RB0 pin mask */ +#define LDD_NFC_CE1_PIN 0x04U /*!< CE1 pin mask */ +#define LDD_NFC_RB1_PIN 0x08U /*!< RB1 pin mask */ +#define LDD_NFC_CE2_PIN 0x10U /*!< CE2 pin mask */ +#define LDD_NFC_RB2_PIN 0x20U /*!< RB2 pin mask */ +#define LDD_NFC_CE3_PIN 0x40U /*!< CE3 pin mask */ +#define LDD_NFC_RB3_PIN 0x80U /*!< RB3 pin mask */ +#define LDD_NFC_ALE_PIN 0x0100U /*!< ALE pin mask */ +#define LDD_NFC_CLE_PIN 0x0200U /*!< CLE pin mask */ +#define LDD_NFC_RE_PIN 0x0400U /*!< RE pin mask */ +#define LDD_NFC_WE_PIN 0x0800U /*!< WE pin mask */ +#define LDD_NFC_D0_PIN 0x00010000U /*!< D0 pin mask */ +#define LDD_NFC_D1_PIN 0x00020000U /*!< D1 pin mask */ +#define LDD_NFC_D2_PIN 0x00040000U /*!< D2 pin mask */ +#define LDD_NFC_D3_PIN 0x00080000U /*!< D3 pin mask */ +#define LDD_NFC_D4_PIN 0x00100000U /*!< D4 pin mask */ +#define LDD_NFC_D5_PIN 0x00200000U /*!< D5 pin mask */ +#define LDD_NFC_D6_PIN 0x00400000U /*!< D6 pin mask */ +#define LDD_NFC_D7_PIN 0x00800000U /*!< D7 pin mask */ +#define LDD_NFC_D8_PIN 0x01000000U /*!< D8 pin mask */ +#define LDD_NFC_D9_PIN 0x02000000U /*!< D9 pin mask */ +#define LDD_NFC_D10_PIN 0x04000000U /*!< D10 pin mask */ +#define LDD_NFC_D11_PIN 0x08000000U /*!< D11 pin mask */ +#define LDD_NFC_D12_PIN 0x10000000U /*!< D12 pin mask */ +#define LDD_NFC_D13_PIN 0x20000000U /*!< D13 pin mask */ +#define LDD_NFC_D14_PIN 0x40000000U /*!< D14 pin mask */ +#define LDD_NFC_D15_PIN 0x80000000U /*!< D15 pin mask */ + +typedef uint32_t LDD_NFC_TTargetID; /*!< NFC target ID type */ + +/*! NCF command codes */ +typedef enum { + LDD_NFC_CMD_NONE = 0x00U, /* No command */ + LDD_NFC_CMD_RESET = 0x01U, /* Reset command */ + LDD_NFC_CMD_ERASE = 0x02U, /* Erase command */ + LDD_NFC_CMD_READ_ID = 0x03U, /* Read ID command */ + LDD_NFC_CMD_READ_PAGES = 0x04U, /* Read pages command */ + LDD_NFC_CMD_WRITE_PAGES = 0x05U, /* Write pages command */ + LDD_NFC_CMD_ERASE_BLOCKS = 0x06U, /* Erase page command */ + LDD_NFC_CMD_READ_RAW_PAGE = 0x07U, /* Read raw page command */ + LDD_NFC_CMD_WRITE_RAW_PAGE = 0x08U /* Write raw page command */ +} LDD_NFC_TeCmd; + +/* +** =================================================================== +** LCDC device types and constants +** =================================================================== +*/ + +#define LDD_LCDC_ON_ERROR 0x01U /*!< OnError event mask */ +#define LDD_LCDC_ON_START_OF_FRAME 0x02U /*!< OnStartOfFrame event mask */ +#define LDD_LCDC_ON_END_OF_FRAME 0x04U /*!< OnEndOfFrame event mask */ + +#define LDD_LCDC_NO_ERR 0x00U /*!< No error */ +#define LDD_LCDC_PLANE_0_UNDERRUN_ERR 0x01U /*!< Plane 0 underrurn error */ +#define LDD_LCDC_PLANE_1_UNDERRUN_ERR 0x02U /*!< Plane 1 underrurn error */ + +#define LDD_LCDC_REVERSED_VERTICAL_SCAN 0x8000U /*!< Enable reversed vertical scan (flip along x-axis) */ + +/*! Bitmap description */ +typedef struct { + LDD_TData *Address; /*!< Bitmap starting address */ + uint16_t Width; /*!< Bitmap width */ + uint16_t Height; /*!< Bitmap height */ + uint16_t Format; /*!< Bitmap format */ +} LDD_LCDC_TBitmap; + +/*! Window description */ +typedef struct { + uint16_t X; /*!< Window position in bitmap - X */ + uint16_t Y; /*!< Window position in bitmap - Y */ + uint16_t Width; /*!< Window width */ + uint16_t Height; /*!< Window height */ +} LDD_LCDC_TWindow; + +/*! Cursor type */ +typedef enum { + LDD_LCDC_DISABLED = 0, /*!< Cursor disabled */ + LDD_LCDC_ALWAYS_1, /*!< Cursor 1''s, monochrome display only. */ + LDD_LCDC_ALWAYS_0, /*!< Cursor 0''s, monochrome display only. */ + LDD_LCDC_COLOR, /*!< Defined cursor color, color display only. */ + LDD_LCDC_INVERTED, /*!< Inverted background, monochrome display only. */ + LDD_LCDC_INVERTED_COLOR, /*!< Inverted cursor color, color display only. */ + LDD_LCDC_AND, /*!< Cursor color AND backgroun, color display only. */ + LDD_LCDC_OR, /*!< Cursor color OR backgroun, color display only. */ + LDD_LCDC_XOR +} LDD_LCDC_CursorOperation; + +/*! Plane identification */ +typedef enum { + LDD_LCDC_PLANE_COMMON, /*!< Common for all planes */ + LDD_LCDC_PLANE_0, /*!< Plane (layer) 0 */ + LDD_LCDC_PLANE_1 /*!< Plane (layer) 1 */ +} LDD_LCDC_TPlaneID; + + +/* +** =================================================================== +** Interrupt vector constants +** =================================================================== +*/ +#define LDD_ivIndex_INT_Initial_Stack_Pointer 0x00u +#define LDD_ivIndex_INT_Initial_Program_Counter 0x01u +#define LDD_ivIndex_INT_NMI 0x02u +#define LDD_ivIndex_INT_Hard_Fault 0x03u +#define LDD_ivIndex_INT_Mem_Manage_Fault 0x04u +#define LDD_ivIndex_INT_Bus_Fault 0x05u +#define LDD_ivIndex_INT_Usage_Fault 0x06u +#define LDD_ivIndex_INT_Reserved7 0x07u +#define LDD_ivIndex_INT_Reserved8 0x08u +#define LDD_ivIndex_INT_Reserved9 0x09u +#define LDD_ivIndex_INT_Reserved10 0x0Au +#define LDD_ivIndex_INT_SVCall 0x0Bu +#define LDD_ivIndex_INT_DebugMonitor 0x0Cu +#define LDD_ivIndex_INT_Reserved13 0x0Du +#define LDD_ivIndex_INT_PendableSrvReq 0x0Eu +#define LDD_ivIndex_INT_SysTick 0x0Fu +#define LDD_ivIndex_INT_DMA0 0x10u +#define LDD_ivIndex_INT_DMA1 0x11u +#define LDD_ivIndex_INT_DMA2 0x12u +#define LDD_ivIndex_INT_DMA3 0x13u +#define LDD_ivIndex_INT_DMA4 0x14u +#define LDD_ivIndex_INT_DMA5 0x15u +#define LDD_ivIndex_INT_DMA6 0x16u +#define LDD_ivIndex_INT_DMA7 0x17u +#define LDD_ivIndex_INT_DMA8 0x18u +#define LDD_ivIndex_INT_DMA9 0x19u +#define LDD_ivIndex_INT_DMA10 0x1Au +#define LDD_ivIndex_INT_DMA11 0x1Bu +#define LDD_ivIndex_INT_DMA12 0x1Cu +#define LDD_ivIndex_INT_DMA13 0x1Du +#define LDD_ivIndex_INT_DMA14 0x1Eu +#define LDD_ivIndex_INT_DMA15 0x1Fu +#define LDD_ivIndex_INT_DMA_Error 0x20u +#define LDD_ivIndex_INT_MCM 0x21u +#define LDD_ivIndex_INT_FTF 0x22u +#define LDD_ivIndex_INT_Read_Collision 0x23u +#define LDD_ivIndex_INT_LVD_LVW 0x24u +#define LDD_ivIndex_INT_LLWU 0x25u +#define LDD_ivIndex_INT_WDOG_EWM 0x26u +#define LDD_ivIndex_INT_RNG 0x27u +#define LDD_ivIndex_INT_I2C0 0x28u +#define LDD_ivIndex_INT_I2C1 0x29u +#define LDD_ivIndex_INT_SPI0 0x2Au +#define LDD_ivIndex_INT_SPI1 0x2Bu +#define LDD_ivIndex_INT_I2S0_Tx 0x2Cu +#define LDD_ivIndex_INT_I2S0_Rx 0x2Du +#define LDD_ivIndex_INT_LPUART0 0x2Eu +#define LDD_ivIndex_INT_UART0_RX_TX 0x2Fu +#define LDD_ivIndex_INT_UART0_ERR 0x30u +#define LDD_ivIndex_INT_UART1_RX_TX 0x31u +#define LDD_ivIndex_INT_UART1_ERR 0x32u +#define LDD_ivIndex_INT_UART2_RX_TX 0x33u +#define LDD_ivIndex_INT_UART2_ERR 0x34u +#define LDD_ivIndex_INT_Reserved53 0x35u +#define LDD_ivIndex_INT_Reserved54 0x36u +#define LDD_ivIndex_INT_ADC0 0x37u +#define LDD_ivIndex_INT_CMP0 0x38u +#define LDD_ivIndex_INT_CMP1 0x39u +#define LDD_ivIndex_INT_FTM0 0x3Au +#define LDD_ivIndex_INT_FTM1 0x3Bu +#define LDD_ivIndex_INT_FTM2 0x3Cu +#define LDD_ivIndex_INT_Reserved61 0x3Du +#define LDD_ivIndex_INT_RTC 0x3Eu +#define LDD_ivIndex_INT_RTC_Seconds 0x3Fu +#define LDD_ivIndex_INT_PIT0 0x40u +#define LDD_ivIndex_INT_PIT1 0x41u +#define LDD_ivIndex_INT_PIT2 0x42u +#define LDD_ivIndex_INT_PIT3 0x43u +#define LDD_ivIndex_INT_PDB0 0x44u +#define LDD_ivIndex_INT_USB0 0x45u +#define LDD_ivIndex_INT_Reserved70 0x46u +#define LDD_ivIndex_INT_Reserved71 0x47u +#define LDD_ivIndex_INT_DAC0 0x48u +#define LDD_ivIndex_INT_MCG 0x49u +#define LDD_ivIndex_INT_LPTMR0 0x4Au +#define LDD_ivIndex_INT_PORTA 0x4Bu +#define LDD_ivIndex_INT_PORTB 0x4Cu +#define LDD_ivIndex_INT_PORTC 0x4Du +#define LDD_ivIndex_INT_PORTD 0x4Eu +#define LDD_ivIndex_INT_PORTE 0x4Fu +#define LDD_ivIndex_INT_SWI 0x50u +#define LDD_ivIndex_INT_Reserved81 0x51u +#define LDD_ivIndex_INT_Reserved82 0x52u +#define LDD_ivIndex_INT_Reserved83 0x53u +#define LDD_ivIndex_INT_Reserved84 0x54u +#define LDD_ivIndex_INT_Reserved85 0x55u +#define LDD_ivIndex_INT_Reserved86 0x56u +#define LDD_ivIndex_INT_FTM3 0x57u +#define LDD_ivIndex_INT_DAC1 0x58u +#define LDD_ivIndex_INT_ADC1 0x59u +#define LDD_ivIndex_INT_Reserved90 0x5Au +#define LDD_ivIndex_INT_Reserved91 0x5Bu +#define LDD_ivIndex_INT_Reserved92 0x5Cu +#define LDD_ivIndex_INT_Reserved93 0x5Du +#define LDD_ivIndex_INT_Reserved94 0x5Eu +#define LDD_ivIndex_INT_Reserved95 0x5Fu +#define LDD_ivIndex_INT_Reserved96 0x60u +#define LDD_ivIndex_INT_Reserved97 0x61u +#define LDD_ivIndex_INT_Reserved98 0x62u +#define LDD_ivIndex_INT_Reserved99 0x63u +#define LDD_ivIndex_INT_Reserved100 0x64u +#define LDD_ivIndex_INT_Reserved101 0x65u + +#endif /* __PE_Types_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.c new file mode 100644 index 0000000..74521f7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.c @@ -0,0 +1,620 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PTRC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PercepioTrace +** Version : Component 01.138, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:18, # CodeGen: 3 +** Abstract : +** +** Settings : +** Component name : PTRC1 +** RTOS+Trace Version : V3.3.0 +** Recorder Mode : Streaming +** Recorder Buffer Allocation : static +** Max ISR Nesting : 8 +** Snapshot Mode : +** Recorder store mode : Ring Buffer +** Scheduling only : no +** Description string : FreeRTOS+Trace +** Description max length : 80 +** Event buffer size : 500 +** Symbol table size : 50 +** Objects : +** Number of tasks : 10 +** Name length for task : configMAX_TASK_NAME_LEN +** Number of ISR : 4 +** Number of queue : 3 +** Number of semaphore : 4 +** Number of mutex : 4 +** Number of timer : 2 +** Number of event groups : 2 +** Name length for ISR : 10 +** Name length for queue : 15 +** Name length for semaphore : 15 +** Name length for mutex : 15 +** Name length for timer : 15 +** Name length for event group : 15 +** Events Creation : +** Include OS Tick events : yes +** Include ready events : yes +** Include memory manager events : yes +** Include ISR tracing : yes +** Include object delete events : yes +** Include user events : yes +** Heap Size below 16M : no +** Float support : no +** Use implicit IFE rules : yes +** Use 16bit Object Handles : no +** Segger RTT : Disabled +** Streaming Mode : +** Up Buffer Index : 2 +** Up Buffer Size : 1024 +** Down Buffer Index : 2 +** Down Buffer Size : 32 +** Symbol Table Slots : 30 +** Symbol Max Length : 24 +** Object Data Slots : 20 +** Ctrl Task Priority : 1 +** Ctrl Task Stack Size : 500/sizeof(StackType_t) +** Ctrl Task Delay : ((10 * configTICK_RATE_HZ) / 1000) +** Source Folders : Disabled +** System : +** SDK : MCUC1 +** Utility : UTIL1 +** Contents : +** vTraceEnable - void PTRC1_vTraceEnable(int startOption); +** uiTraceStart - dword PTRC1_uiTraceStart(void); +** vTraceStop - void PTRC1_vTraceStop(void); +** vTraceClear - void PTRC1_vTraceClear(void); +** uiTraceGetTraceBufferSize - dword PTRC1_uiTraceGetTraceBufferSize(void); +** xTraceGetTraceBuffer - void* PTRC1_xTraceGetTraceBuffer(void); +** xTraceRegisterString - traceString PTRC1_xTraceRegisterString(const char* name); +** vTracePrint - void PTRC1_vTracePrint(traceString chn, const char* str); +** vTracePrintF - void PTRC1_vTracePrintF(traceLabel eventLabel, char *formatStr, ...); +** vTraceSetQueueName - void PTRC1_vTraceSetQueueName(void *queue, char *name); +** vTraceSetSemaphoreName - void PTRC1_vTraceSetSemaphoreName(void *semaphore, char *name); +** vTraceSetMutexName - void PTRC1_vTraceSetMutexName(void *mutex, char *name); +** xTraceSetISRProperties - traceHandle PTRC1_xTraceSetISRProperties(char *name, char prioritiy); +** vTraceStoreISRBegin - void PTRC1_vTraceStoreISRBegin(traceHandle handle); +** vTraceStoreISREnd - void PTRC1_vTraceStoreISREnd(int isTaskSwitchRequired); +** vGetGDBDumpCommand - void PTRC1_vGetGDBDumpCommand(uint8_t *buf, uint16_t bufSize, uint8_t... +** vTraceSetStopHook - void PTRC1_vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction); +** xTraceGetLastError - char* PTRC1_xTraceGetLastError(void); +** vTraceClearError - byte PTRC1_vTraceClearError(int resetErrorMessage); +** Startup - void PTRC1_Startup(void); +** +** * (c) Copyright Percepio AB, 2013-2018 +** * http : www.percepio.se +** * mail : info@percepio.com +** * See separate Percepio licensing terms. +** * +** * Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file PTRC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup PTRC1_module PTRC1 module documentation +** @{ +*/ + +/* MODULE PTRC1. */ +#include "PTRC1.h" +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "Events.h" +#endif + +/* +** =================================================================== +** Method : uiTraceGetTraceBufferSize (component PercepioTrace) +** +** Description : +** Gets the size of the recorder data structure. For use +** together with vTraceGetTraceBuffer if you wish to implement +** an own store/upload solution, e.g., in case a debugger +** connection is not available for uploading the data. +** Parameters : None +** Returns : +** --- - Size of the trace buffer +** =================================================================== +*/ +/* +dword PTRC1_uiTraceGetTraceBufferSize(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : xTraceGetTraceBuffer (component PercepioTrace) +** +** Description : +** Return a pointer to the recorder data structure. Use this +** together with uiTraceGetTraceBufferSize if you wish to +** implement an own store/upload solution, e.g., in case a +** debugger connection is not available for uploading the data. +** Parameters : None +** Returns : +** --- - Pointer to the trace buffer +** =================================================================== +*/ +/* +void* PTRC1_xTraceGetTraceBuffer(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : uiTraceStart (component PercepioTrace) +** +** Description : +** Starts the trace. +** Parameters : None +** Returns : +** --- - returns 1 if trace has been started, 0 +** otherwise. +** =================================================================== +*/ +/* +dword PTRC1_uiTraceStart(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceStop (component PercepioTrace) +** +** Description : +** Stops the trace. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceStop(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceClear (component PercepioTrace) +** +** Description : +** Clears the trace. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceClear(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : xTraceRegisterString (component PercepioTrace) +** +** Description : +** Register strings in the recorder, e.g. for names of user +** event channels. +** Parameters : +** NAME - DESCRIPTION +** * name - Pointer to label +** Returns : +** --- - trace label to be used with vTracePrintF +** =================================================================== +*/ +/* +traceString PTRC1_xTraceRegisterString(const char* name) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTracePrint (component PercepioTrace) +** +** Description : +** Generates a User Event with a text label. The label is +** created/looked up in the symbol table using +** xTraceRegisterString. +** Parameters : +** NAME - DESCRIPTION +** chn - trace label for the user event +** * str - Pointer to string +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTracePrint(traceString chn, const char* str) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTracePrintF (component PercepioTrace) +** +** Description : +** Advanced user event - like printf (but limited formatting +** support - will improve) +** Parameters : +** NAME - DESCRIPTION +** eventLabel - trace label +** * formatStr - Pointer to format string +** Variable_1 - open parameter list +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTracePrintF(traceLabel eventLabel, char *formatStr, ...) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceSetQueueName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the queue +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceSetQueueName(void *queue, char *name) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : xTraceSetISRProperties (component PercepioTrace) +** +** Description : +** Registers an Interrupt Service Routine in the recorder +** library, This must be called before using +** vTraceStoreISRBegin to store ISR events. This is typically +** called in the startup of the system, before the scheduler is +** started. Method is always enabled if 'Include ISR tracing' +** is set to 'yes' in the properties. +** Parameters : +** NAME - DESCRIPTION +** * name - Pointer to name +** prioritiy - priority +** Returns : +** --- - trace handle to be used for +** vTaceStoreISRBegin() +** =================================================================== +*/ +/* +traceHandle PTRC1_xTraceSetISRProperties(char *name, char prioritiy) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceStoreISRBegin (component PercepioTrace) +** +** Description : +** Registers the beginning of an Interrupt Service Routine. +** This must not be interrupted by another ISR containing +** recorder library calls, so if allowing nested ISRs this must +** be called with interrupts disabled. Method is always +** enabled if 'Include ISR tracing' is set to 'yes' in the +** properties. +** Parameters : +** NAME - DESCRIPTION +** handle - trace handle +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceStoreISRBegin(traceHandle handle) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceStoreISREnd (component PercepioTrace) +** +** Description : +** Registers the end of an Interrupt Service Routine. This must +** not be interrupted by another ISR containing recorder +** library calls, so if allowing nested ISRs this must be +** called with interrupts disabled. Method is always enabled +** if 'Include ISR tracing' is set to 'yes' in the properties. +** Parameters : +** NAME - DESCRIPTION +** isTaskSwitchRequired - The +** parameter pendingISR indicates if the +** interrupt has requested a task-switch (= 1) +** or if the interrupt returns to the earlier +** context (= 0) +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceStoreISREnd(int isTaskSwitchRequired) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vGetGDBDumpCommand (component PercepioTrace) +** +** Description : +** Gets the gdb command to dump the trace data to a file. +** Useful for copy-pasting it to the gdb console. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer for the command. Make it +** large enoug (about 64 bytes) +** bufSize - size of the buffer +** * fileName - Pointer to the file name string, +** e.g. "C:\\tmp\\trace.dump" +** Returns : Nothing +** =================================================================== +*/ +void PTRC1_vGetGDBDumpCommand(uint8_t *buf, uint16_t bufSize, uint8_t *fileName) +{ +#if !TRC_USE_TRACEALYZER_RECORDER || (TRC_CFG_RECORDER_MODE==TRC_RECORDER_MODE_STREAMING) /* trace disabled or streaming mode */ + (void)bufSize; /* not used */ + (void)fileName; /* not used */ + /* with RTT streaming, there is no trace buffer */ + *buf = '\0'; +#else + /* construct gdb command string: dump binary memory */ + uint8_t *ptr; /* pointer to data */ + size_t len; /* size/length of data */ + + ptr = (uint8_t*)PTRC1_xTraceGetTraceBuffer(); + len = PTRC1_uiTraceGetTraceBufferSize(); + UTIL1_strcpy(buf, bufSize, (unsigned char*)"dump binary memory "); + UTIL1_strcat(buf, bufSize, fileName); + UTIL1_strcat(buf, bufSize, (unsigned char*)" 0x"); + UTIL1_strcatNum32Hex(buf, bufSize, (uint32_t)ptr); + UTIL1_strcat(buf, bufSize, (unsigned char*)" 0x"); + UTIL1_strcatNum32Hex(buf, bufSize, (uint32_t)(ptr+len)); +#endif +} + +/* +** =================================================================== +** Method : vTraceSetStopHook (component PercepioTrace) +** +** Description : +** Sets a function to be called when the recorder is stopped. +** Parameters : +** NAME - DESCRIPTION +** stopHookFunction - +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : xTraceGetLastError (component PercepioTrace) +** +** Description : +** Gives the last error message, if any. NULL if no error +** message is stored. Any error message is also presented when +** opening a trace file. +** Parameters : None +** Returns : +** --- - Error message +** =================================================================== +*/ +/* +char* PTRC1_xTraceGetLastError(void) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceClearError (component PercepioTrace) +** +** Description : +** Removes any previous error message generated by recorder +** calling vTraceError. By calling this function, it may be +** possible to start/restart the trace despite errors in the +** recorder, but there is no guarantee that the trace recorder +** will work correctly in that case, depending on the type of +** error. +** Parameters : +** NAME - DESCRIPTION +** resetErrorMessage - parameter is +** not used +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +byte PTRC1_vTraceClearError(int resetErrorMessage) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceEnable (component PercepioTrace) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** startoption - * TRC_START: Starts the +** tracing directly. In snapshot mode this +** allows for +** * starting the trace at any point in your +** code, assuming vTraceEnable(TRC_INIT) +** * has been called in the startup. +** * Can also be used for streaming without +** Tracealyzer control, e.g. to a local +** * flash file system (assuming such a +** "stream port", see trcStreamingPort.h). +** * +** * TRC_START_AWAIT_HOST: For streaming mode +** only. Initializes the trace recorder +** * if necessary and waits for a Start +** command from Tracealyzer ("Start Recording" +** * button). This call is intentionally +** blocking! By calling vTraceEnable with +** * this option from the startup code, you +** start tracing at this point and capture +** * the early events. +** * +** * TRC_INIT: Initializes the trace recorder, +** but does not start the tracing. +** * In snapshot mode, this must be followed +** by a vTraceEnable(TRC_START) sometime +** * later. +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceEnable(int startOption) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceSetSemaphoreName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the semaphore +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceSetSemaphoreName(void *semaphore, char *name) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : vTraceSetMutexName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the mutex +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ +/* +void PTRC1_vTraceSetMutexName(void *mutex, char *name) +{ + *** Implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Startup (component PercepioTrace) +** +** Description : +** Routine called during startup. Depending on the mode and +** settings, it starts tracing and might block! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void PTRC1_Startup(void) +{ +#if configUSE_PERCEPIO_TRACE_HOOKS /* FreeRTOS using Percepio Trace */ + vTraceSetFrequency(configSYSTICK_CLOCK_HZ); + vTraceEnable(PTRC1_CONFIG_START_TRACE_IN_STARTUP_MODE); /* snapshot trace, from startup */ +#endif /* configUSE_PERCEPIO_TRACE_HOOKS */ +} + +/* END PTRC1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.h new file mode 100644 index 0000000..7d48928 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1.h @@ -0,0 +1,547 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PTRC1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PercepioTrace +** Version : Component 01.138, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:18, # CodeGen: 3 +** Abstract : +** +** Settings : +** Component name : PTRC1 +** RTOS+Trace Version : V3.3.0 +** Recorder Mode : Streaming +** Recorder Buffer Allocation : static +** Max ISR Nesting : 8 +** Snapshot Mode : +** Recorder store mode : Ring Buffer +** Scheduling only : no +** Description string : FreeRTOS+Trace +** Description max length : 80 +** Event buffer size : 500 +** Symbol table size : 50 +** Objects : +** Number of tasks : 10 +** Name length for task : configMAX_TASK_NAME_LEN +** Number of ISR : 4 +** Number of queue : 3 +** Number of semaphore : 4 +** Number of mutex : 4 +** Number of timer : 2 +** Number of event groups : 2 +** Name length for ISR : 10 +** Name length for queue : 15 +** Name length for semaphore : 15 +** Name length for mutex : 15 +** Name length for timer : 15 +** Name length for event group : 15 +** Events Creation : +** Include OS Tick events : yes +** Include ready events : yes +** Include memory manager events : yes +** Include ISR tracing : yes +** Include object delete events : yes +** Include user events : yes +** Heap Size below 16M : no +** Float support : no +** Use implicit IFE rules : yes +** Use 16bit Object Handles : no +** Segger RTT : Disabled +** Streaming Mode : +** Up Buffer Index : 2 +** Up Buffer Size : 1024 +** Down Buffer Index : 2 +** Down Buffer Size : 32 +** Symbol Table Slots : 30 +** Symbol Max Length : 24 +** Object Data Slots : 20 +** Ctrl Task Priority : 1 +** Ctrl Task Stack Size : 500/sizeof(StackType_t) +** Ctrl Task Delay : ((10 * configTICK_RATE_HZ) / 1000) +** Source Folders : Disabled +** System : +** SDK : MCUC1 +** Utility : UTIL1 +** Contents : +** vTraceEnable - void PTRC1_vTraceEnable(int startOption); +** uiTraceStart - dword PTRC1_uiTraceStart(void); +** vTraceStop - void PTRC1_vTraceStop(void); +** vTraceClear - void PTRC1_vTraceClear(void); +** uiTraceGetTraceBufferSize - dword PTRC1_uiTraceGetTraceBufferSize(void); +** xTraceGetTraceBuffer - void* PTRC1_xTraceGetTraceBuffer(void); +** xTraceRegisterString - traceString PTRC1_xTraceRegisterString(const char* name); +** vTracePrint - void PTRC1_vTracePrint(traceString chn, const char* str); +** vTracePrintF - void PTRC1_vTracePrintF(traceLabel eventLabel, char *formatStr, ...); +** vTraceSetQueueName - void PTRC1_vTraceSetQueueName(void *queue, char *name); +** vTraceSetSemaphoreName - void PTRC1_vTraceSetSemaphoreName(void *semaphore, char *name); +** vTraceSetMutexName - void PTRC1_vTraceSetMutexName(void *mutex, char *name); +** xTraceSetISRProperties - traceHandle PTRC1_xTraceSetISRProperties(char *name, char prioritiy); +** vTraceStoreISRBegin - void PTRC1_vTraceStoreISRBegin(traceHandle handle); +** vTraceStoreISREnd - void PTRC1_vTraceStoreISREnd(int isTaskSwitchRequired); +** vGetGDBDumpCommand - void PTRC1_vGetGDBDumpCommand(uint8_t *buf, uint16_t bufSize, uint8_t... +** vTraceSetStopHook - void PTRC1_vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction); +** xTraceGetLastError - char* PTRC1_xTraceGetLastError(void); +** vTraceClearError - byte PTRC1_vTraceClearError(int resetErrorMessage); +** Startup - void PTRC1_Startup(void); +** +** * (c) Copyright Percepio AB, 2013-2018 +** * http : www.percepio.se +** * mail : info@percepio.com +** * See separate Percepio licensing terms. +** * +** * Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file PTRC1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup PTRC1_module PTRC1 module documentation +** @{ +*/ + +#ifndef __PTRC1_HvTraceInitTraceData +#define __PTRC1_H + +/* MODULE PTRC1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "PTRC1config.h" /* configuration */ + +/* Include inherited components */ +#include "MCUC1.h" +#include "UTIL1.h" + +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + /* prototypes for user events */ + void PTRC1_OnTraceWrap(void); +#endif + +#include "trcRecorder.h" /* streaming interface */ + + +#define PTRC1_uiTraceGetTraceBufferSize() \ + uiTraceGetTraceBufferSize() + +/* +** =================================================================== +** Method : uiTraceGetTraceBufferSize (component PercepioTrace) +** +** Description : +** Gets the size of the recorder data structure. For use +** together with vTraceGetTraceBuffer if you wish to implement +** an own store/upload solution, e.g., in case a debugger +** connection is not available for uploading the data. +** Parameters : None +** Returns : +** --- - Size of the trace buffer +** =================================================================== +*/ + +#define PTRC1_xTraceGetTraceBuffer() \ + xTraceGetTraceBuffer() + +/* +** =================================================================== +** Method : xTraceGetTraceBuffer (component PercepioTrace) +** +** Description : +** Return a pointer to the recorder data structure. Use this +** together with uiTraceGetTraceBufferSize if you wish to +** implement an own store/upload solution, e.g., in case a +** debugger connection is not available for uploading the data. +** Parameters : None +** Returns : +** --- - Pointer to the trace buffer +** =================================================================== +*/ + +#define PTRC1_uiTraceStart() \ + uiTraceStart() +/* +** =================================================================== +** Method : uiTraceStart (component PercepioTrace) +** +** Description : +** Starts the trace. +** Parameters : None +** Returns : +** --- - returns 1 if trace has been started, 0 +** otherwise. +** =================================================================== +*/ + +#define PTRC1_vTraceStop() \ + vTraceStop() + +/* +** =================================================================== +** Method : vTraceStop (component PercepioTrace) +** +** Description : +** Stops the trace. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceClear() \ + vTraceClear() + +/* +** =================================================================== +** Method : vTraceClear (component PercepioTrace) +** +** Description : +** Clears the trace. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_xTraceRegisterString (label) \ + xTraceRegisterString(label) + +/* +** =================================================================== +** Method : xTraceRegisterString (component PercepioTrace) +** +** Description : +** Register strings in the recorder, e.g. for names of user +** event channels. +** Parameters : +** NAME - DESCRIPTION +** * name - Pointer to label +** Returns : +** --- - trace label to be used with vTracePrintF +** =================================================================== +*/ + +#define PTRC1_vTracePrint(chn, str) \ + vTracePrint(chn, str) + +/* +** =================================================================== +** Method : vTracePrint (component PercepioTrace) +** +** Description : +** Generates a User Event with a text label. The label is +** created/looked up in the symbol table using +** xTraceRegisterString. +** Parameters : +** NAME - DESCRIPTION +** chn - trace label for the user event +** * str - Pointer to string +** Returns : Nothing +** =================================================================== +*/ + +/* void PTRC1_vTracePrintF(traceLabel eventLabel, char *formatStr, ...); */ +#define PTRC1_vTracePrintF vTracePrintF + +/* +** =================================================================== +** Method : vTracePrintF (component PercepioTrace) +** +** Description : +** Advanced user event - like printf (but limited formatting +** support - will improve) +** Parameters : +** NAME - DESCRIPTION +** eventLabel - trace label +** * formatStr - Pointer to format string +** Variable_1 - open parameter list +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceSetQueueName(queue, name) \ + vTraceSetQueueName(queue, name) + +/* +** =================================================================== +** Method : vTraceSetQueueName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the queue +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_xTraceSetISRProperties(name, prioritiy) \ + xTraceSetISRProperties(name, prioritiy) + +/* +** =================================================================== +** Method : xTraceSetISRProperties (component PercepioTrace) +** +** Description : +** Registers an Interrupt Service Routine in the recorder +** library, This must be called before using +** vTraceStoreISRBegin to store ISR events. This is typically +** called in the startup of the system, before the scheduler is +** started. Method is always enabled if 'Include ISR tracing' +** is set to 'yes' in the properties. +** Parameters : +** NAME - DESCRIPTION +** * name - Pointer to name +** prioritiy - priority +** Returns : +** --- - trace handle to be used for +** vTaceStoreISRBegin() +** =================================================================== +*/ + +#define PTRC1_vTraceStoreISRBegin(handle) \ + vTraceStoreISRBegin(handle) + +/* +** =================================================================== +** Method : vTraceStoreISRBegin (component PercepioTrace) +** +** Description : +** Registers the beginning of an Interrupt Service Routine. +** This must not be interrupted by another ISR containing +** recorder library calls, so if allowing nested ISRs this must +** be called with interrupts disabled. Method is always +** enabled if 'Include ISR tracing' is set to 'yes' in the +** properties. +** Parameters : +** NAME - DESCRIPTION +** handle - trace handle +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceStoreISREnd(isTaskSwitchRequired) \ + vTraceStoreISREnd(isTaskSwitchRequired) + +/* +** =================================================================== +** Method : vTraceStoreISREnd (component PercepioTrace) +** +** Description : +** Registers the end of an Interrupt Service Routine. This must +** not be interrupted by another ISR containing recorder +** library calls, so if allowing nested ISRs this must be +** called with interrupts disabled. Method is always enabled +** if 'Include ISR tracing' is set to 'yes' in the properties. +** Parameters : +** NAME - DESCRIPTION +** isTaskSwitchRequired - The +** parameter pendingISR indicates if the +** interrupt has requested a task-switch (= 1) +** or if the interrupt returns to the earlier +** context (= 0) +** Returns : Nothing +** =================================================================== +*/ + +void PTRC1_vGetGDBDumpCommand(uint8_t *buf, uint16_t bufSize, uint8_t *fileName); +/* +** =================================================================== +** Method : vGetGDBDumpCommand (component PercepioTrace) +** +** Description : +** Gets the gdb command to dump the trace data to a file. +** Useful for copy-pasting it to the gdb console. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer for the command. Make it +** large enoug (about 64 bytes) +** bufSize - size of the buffer +** * fileName - Pointer to the file name string, +** e.g. "C:\\tmp\\trace.dump" +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceSetStopHook(stopHookFunction) \ + vTraceSetStopHook(stopHookFunction) +/* +** =================================================================== +** Method : vTraceSetStopHook (component PercepioTrace) +** +** Description : +** Sets a function to be called when the recorder is stopped. +** Parameters : +** NAME - DESCRIPTION +** stopHookFunction - +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_xTraceGetLastError() \ + xTraceGetLastError() +/* +** =================================================================== +** Method : xTraceGetLastError (component PercepioTrace) +** +** Description : +** Gives the last error message, if any. NULL if no error +** message is stored. Any error message is also presented when +** opening a trace file. +** Parameters : None +** Returns : +** --- - Error message +** =================================================================== +*/ + +#define PTRC1_vTraceClearError(resetErrorMessage) \ + vTraceClearError(resetErrorMessage) +/* +** =================================================================== +** Method : vTraceClearError (component PercepioTrace) +** +** Description : +** Removes any previous error message generated by recorder +** calling vTraceError. By calling this function, it may be +** possible to start/restart the trace despite errors in the +** recorder, but there is no guarantee that the trace recorder +** will work correctly in that case, depending on the type of +** error. +** Parameters : +** NAME - DESCRIPTION +** resetErrorMessage - parameter is +** not used +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define PTRC1_vTraceEnable(startOption) \ + vTraceEnable(startOption) +/* +** =================================================================== +** Method : vTraceEnable (component PercepioTrace) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** startoption - * TRC_START: Starts the +** tracing directly. In snapshot mode this +** allows for +** * starting the trace at any point in your +** code, assuming vTraceEnable(TRC_INIT) +** * has been called in the startup. +** * Can also be used for streaming without +** Tracealyzer control, e.g. to a local +** * flash file system (assuming such a +** "stream port", see trcStreamingPort.h). +** * +** * TRC_START_AWAIT_HOST: For streaming mode +** only. Initializes the trace recorder +** * if necessary and waits for a Start +** command from Tracealyzer ("Start Recording" +** * button). This call is intentionally +** blocking! By calling vTraceEnable with +** * this option from the startup code, you +** start tracing at this point and capture +** * the early events. +** * +** * TRC_INIT: Initializes the trace recorder, +** but does not start the tracing. +** * In snapshot mode, this must be followed +** by a vTraceEnable(TRC_START) sometime +** * later. +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceSetSemaphoreName(semaphore, name) \ + vTraceSetSemaphoreName(semaphore, name) +/* +** =================================================================== +** Method : vTraceSetSemaphoreName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the semaphore +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ + +#define PTRC1_vTraceSetMutexName(mutex, name) \ + vTraceSetMutexName(mutex, name) +/* +** =================================================================== +** Method : vTraceSetMutexName (component PercepioTrace) +** +** Description : +** Assigns a name to a FreeRTOS Queue, Semaphore or Mutex. This +** function should be called right after creation of the +** queue/mutex/semaphore. If not using this function, the +** queues/mutexes/semaphores will be presented by their numeric +** handle only. +** Parameters : +** NAME - DESCRIPTION +** * queue - Pointer to the mutex +** * name - Pointer to name +** Returns : Nothing +** =================================================================== +*/ + +void PTRC1_Startup(void); +/* +** =================================================================== +** Method : Startup (component PercepioTrace) +** +** Description : +** Routine called during startup. Depending on the mode and +** settings, it starts tracing and might block! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END PTRC1. */ + +#endif +/* ifndef __PTRC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1config.h new file mode 100644 index 0000000..49e287a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/PTRC1config.h @@ -0,0 +1,36 @@ +/** + * \file + * \brief Configuration header file for Percepio Trace for FreeRTOS + * + * This header file is used to configure settings of the Percepio trace. + */ + +#ifndef __PTRC1_CONFIG_H +#define __PTRC1_CONFIG_H + +#include "trcPortDefines.h" +#include "trcConfig.h" + +#if !defined(TRC_CFG_RECORDER_MODE) || !defined(TRC_RECORDER_MODE_SNAPSHOT) + #error "these macros are used below, but do not exist?" +#endif + +#ifndef PTRC1_CONFIG_START_TRACE_IN_STARTUP_MODE + /* Percepio trace startup mode used for calling vTraceEnable() from Startup(): + Snapshot Mode: + TRC_INIT: Initializes trace module. Application needs to start tracing later with vTraceEnable(TRC_START); + TRC_START: Initializes and starts tracing + Streaming Mode: + TRC_INIT: Initializes trace module. Application needs to start tracing later with vTraceEnable(TRC_START); + TRC_START: Initializes and starts tracing + TRC_START_AWAIT_HOST: Initializes trace module and blocks and waits for data to be retrieved */ + #if TRC_CFG_RECORDER_MODE==TRC_RECORDER_MODE_SNAPSHOT + #define PTRC1_CONFIG_START_TRACE_IN_STARTUP_MODE TRC_START + /*!< Trace startup for snapshot mode: TRC_INIT or TRC_START */ + #else /* streaming mode */ + #define PTRC1_CONFIG_START_TRACE_IN_STARTUP_MODE TRC_START + /*!< Trace startup for streaming mode: TRC_INIT, TRC_START or TRC_START_AWAIT_HOST */ + #endif +#endif + +#endif /* __PTRC1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.c new file mode 100644 index 0000000..1a1c7af --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.c @@ -0,0 +1,991 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Pins1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PinSettings +** Version : Component 01.100, Driver 1.1, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** +** Settings : +** Component name : Pins1 +** PinSettings IP Block : PinSettings +** Processor : MK22FN512LH12 +** Pin settings : +** Routing : +** Peripheral Type ADC : +** Custom name : ADC0 +** ADC0 : +** DM0 - Minus channel 0 : ADC0_DM0/ADC1_DM3 +** DM3 - Minus channel 3 : ADC1_DM0/ADC0_DM3 +** DM26 - Minus channel 26 : TempSensor_minus +** DM27 - Minus channel 27 : Bandgap_minus +** DM29 - Minus channel 29 : +** DP0 - Plus channel 0 : ADC0_DP0/ADC1_DP3 +** DP3 - Plus channel 3 : ADC1_DP0/ADC0_DP3 +** DP26 - Plus channel 26 : TempSensor_plus +** DP27 - Plus channel 27 : Bandgap_plus +** DP29 - Plus channel 29 : +** SE0 - Single-ended channel 0 : ADC0_DP0/ADC1_DP3 +** SE3 - Single-ended channel 3 : ADC1_DP0/ADC0_DP3 +** SE8 - Single-ended channel 8 : +** SE9 - Single-ended channel 9 : +** SE12 - Single-ended channel 12 : +** SE13 - Single-ended channel 13 : +** SE14 - Single-ended channel 14 : +** SE15 - Single-ended channel 15 : +** SE19 - Single-ended channel 19 : ADC0_DM0/ADC1_DM3 +** SE23 - Single-ended channel 23 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** SE26 - Single-ended channel 26 : TempSensor +** SE27 - Single-ended channel 27 : Bandgap +** SE29 - Single-ended channel 29 : +** SE30 - Single-ended channel 30 : +** SE4b - Single-ended channel 4b : +** SE5b - Single-ended channel 5b : +** SE6b - Single-ended channel 6b : +** SE7b - Single-ended channel 7b : +** Trigger A input : +** Trigger B input : +** Voltage reference high : +** Voltage reference low : +** Custom name : ADC1 +** ADC1 : +** DM0 - Minus channel 0 : ADC1_DM0/ADC0_DM3 +** DM3 - Minus channel 3 : ADC0_DM0/ADC1_DM3 +** DM26 - Minus channel 26 : TempSensor_minus +** DM27 - Minus channel 27 : Bandgap_minus +** DM29 - Minus channel 29 : +** DP0 - Plus channel 0 : ADC1_DP0/ADC0_DP3 +** DP3 - Plus channel 3 : ADC0_DP0/ADC1_DP3 +** DP26 - Plus channel 26 : TempSensor_plus +** DP27 - Plus channel 27 : Bandgap_plus +** DP29 - Plus channel 29 : +** SE0 - Single-ended channel 0 : ADC1_DP0/ADC0_DP3 +** SE3 - Single-ended channel 3 : ADC0_DP0/ADC1_DP3 +** SE8 - Single-ended channel 8 : +** SE9 - Single-ended channel 9 : +** SE18 - Single-ended channel 18 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** SE19 - Single-ended channel 19 : ADC1_DM0/ADC0_DM3 +** SE23 - Single-ended channel 23 : DAC12b1_Output +** SE26 - Single-ended channel 26 : TempSensor +** SE27 - Single-ended channel 27 : Bandgap +** SE29 - Single-ended channel 29 : +** SE30 - Single-ended channel 30 : +** SE4a - Single-ended channel 4a : +** SE5a - Single-ended channel 5a : +** SE4b - Single-ended channel 4b : +** SE5b - Single-ended channel 5b : +** SE6b - Single-ended channel 6b : +** SE7b - Single-ended channel 7b : +** Trigger A input : +** Trigger B input : +** Voltage reference high : +** Voltage reference low : +** Peripheral Type CMP : +** Custom name : CMP0 +** CMP0 : +** IN0 - Negative input 0 : +** IN1 - Negative input 1 : +** IN2 - Negative input 2 : +** IN3 - Negative input 3 : +** IN4 - Negative input 4 : DAC12b1_Output +** IN5 - Negative input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Negative input 6 : Bandgap +** IN7 - Negative input 7 : DAC6b0_Output +** OUT - Comparator output : +** IN0 - Positive input 0 : +** IN1 - Positive input 1 : +** IN2 - Positive input 2 : +** IN3 - Positive input 3 : +** IN4 - Positive input 4 : DAC12b1_Output +** IN5 - Positive input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Positive input 6 : Bandgap +** IN7 - Positive input 7 : DAC6b0_Output +** Window/sample input : PDB0_PulseOut0 +** Custom name : CMP1 +** CMP1 : +** IN0 - Negative input 0 : +** IN1 - Negative input 1 : +** IN3 - Negative input 3 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** IN5 - Negative input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Negative input 6 : Bandgap +** IN7 - Negative input 7 : DAC6b1_Output +** OUT - Comparator output : +** IN0 - Positive input 0 : +** IN1 - Positive input 1 : +** IN3 - Positive input 3 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** IN5 - Positive input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Positive input 6 : Bandgap +** IN7 - Positive input 7 : DAC6b1_Output +** Window/sample input : PDB0_PulseOut1 +** Peripheral Type CRC : +** Custom name : CRC +** Peripheral Type CoreDebug : +** Peripheral Type DAC : +** Custom name : DAC0 +** DAC0 : +** Output pin : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** Trigger input : PDB0_DAC0_Trigger +** Custom name : DAC1 +** DAC1 : +** Trigger input : PDB0_DAC1_Trigger +** Peripheral Type DMA : +** Custom name : DMA +** DMA : +** Channel 0 trigger : +** Channel 1 trigger : +** Channel 2 trigger : +** Channel 3 trigger : +** Channel 4 trigger : +** Channel 5 trigger : +** Channel 6 trigger : +** Channel 7 trigger : +** Channel 8 trigger : +** Channel 9 trigger : +** Channel 10 trigger : +** Channel 11 trigger : +** Channel 12 trigger : +** Channel 13 trigger : +** Channel 14 trigger : +** Channel 15 trigger : +** Channel 0 periodic trigger : +** Channel 1 periodic trigger : +** Channel 2 periodic trigger : +** Channel 3 periodic trigger : +** Peripheral Type DMAMUX : +** Custom name : DMAMUX +** Peripheral Type DWT : +** Peripheral Type ETF : +** Peripheral Type ETM : +** Peripheral Type EWM : +** Custom name : EWM +** EWM : +** Input pin : +** Output pin : +** Peripheral Type FB : +** Custom name : FB +** FB : +** AD0 - Address/data bus 0 : +** AD1 - Address/data bus 1 : +** AD2 - Address/data bus 2 : +** AD3 - Address/data bus 3 : +** AD4 - Address/data bus 4 : +** AD5 - Address/data bus 5 : +** AD6 - Address/data bus 6 : +** AD7 - Address/data bus 7 : +** AD8 - Address/data bus 8 : +** AD9 - Address/data bus 9 : +** AD10 - Address/data bus 10 : +** AD11 - Address/data bus 11 : +** AD12 - Address/data bus 12 : +** AD13 - Address/data bus 13 : +** AD14 - Address/data bus 14 : +** AD15 - Address/data bus 15 : +** AD16 - Address/data bus 16 : +** AD17 - Address/data bus 17 : +** ALE - Address latch enable : +** CS0 - Chip select 0 : +** CS1 - Chip select 1 : +** OE - Output enable : +** RW - Read/write : +** TS - Transfer start : +** Peripheral Type FMC : +** Custom name : FMC +** Peripheral Type FPB : +** Peripheral Type FTFA : +** Custom name : FTFA +** Peripheral Type FTM : +** Custom name : FTM0 +** FTM0 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CH2 - Channel 2 : +** Direction : +** CH3 - Channel 3 : +** Direction : +** CH4 - Channel 4 : +** Direction : +** CH5 - Channel 5 : +** Direction : +** CH6 - Channel 6 : +** Direction : +** CH7 - Channel 7 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** FLT2 - Fault input 2 : +** FLT3 - Fault input 3 : +** Trigger input 0 : +** Trigger input 1 : +** Trigger input 2 : +** Custom name : FTM1 +** FTM1 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** Quadrature decoder phase A input : +** Quadrature decoder phase B input : +** Trigger input 0 : +** Trigger input 1 : +** Trigger input 2 : +** Custom name : FTM2 +** FTM2 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** Quadrature decoder phase A input : +** Quadrature decoder phase B input : +** Trigger input 0 : +** Trigger input 2 : +** Custom name : FTM3 +** FTM3 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CH2 - Channel 2 : +** Direction : +** CH3 - Channel 3 : +** Direction : +** CH4 - Channel 4 : +** Direction : +** CH5 - Channel 5 : +** Direction : +** CH6 - Channel 6 : +** Direction : +** CH7 - Channel 7 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** Trigger input 0 : +** Trigger input 1 : +** Peripheral Type GPIO : +** Custom name : PTA +** PTA : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 12 : +** Direction : +** Pin 13 : +** Direction : +** Pin 18 : +** Direction : +** Pin 19 : +** Direction : +** Custom name : PTB +** PTB : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 16 : +** Direction : +** Pin 17 : +** Direction : +** Pin 18 : +** Direction : +** Pin 19 : +** Direction : +** Custom name : PTC +** PTC : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 6 : +** Direction : +** Pin 7 : +** Direction : +** Pin 8 : +** Direction : +** Pin 9 : +** Direction : +** Pin 10 : +** Direction : +** Pin 11 : +** Direction : +** Custom name : PTD +** PTD : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 6 : +** Direction : +** Pin 7 : +** Direction : +** Custom name : PTE +** PTE : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Peripheral Type I2C : +** Custom name : I2C0 +** I2C0 : +** SCL - Serial clock : +** SDA - Serial data : +** Custom name : I2C1 +** I2C1 : +** SCL - Serial clock : +** SDA - Serial data : +** Peripheral Type I2S : +** Custom name : I2S0 +** I2S0 : +** MCLK - Master clock : +** RX_BCLK - RX bit clock : +** Direction : +** RX_FS - RX frame sync : +** Direction : +** RXD0 - Receive data 0 : +** TX_BCLK - TX bit clock : +** Direction : +** TX_FS - TX frame sync : +** Direction : +** TXD0 - Transmit data 0 : +** Peripheral Type ITM : +** Peripheral Type JTAG : +** JTAG : +** TCLK - Test clock : +** TDI - Test data input : +** TDO - Test data output : +** TMS - Test mode selection : +** TRST - Reset : +** Peripheral Type LLWU : +** Custom name : LLWU +** LLWU : +** P0 - Wake-up pin 0 : +** P3 - Wake-up pin 3 : +** P4 - Wake-up pin 4 : +** P5 - Wake-up pin 5 : +** P6 - Wake-up pin 6 : +** P7 - Wake-up pin 7 : +** P8 - Wake-up pin 8 : +** P9 - Wake-up pin 9 : +** P10 - Wake-up pin 10 : +** P11 - Wake-up pin 11 : +** P12 - Wake-up pin 12 : +** P13 - Wake-up pin 13 : +** P14 - Wake-up pin 14 : +** P15 - Wake-up pin 15 : +** Peripheral Type LPTMR : +** Custom name : LPTMR0 +** LPTMR0 : +** Pulse counter input 0 : +** Pulse counter input 1 : +** Pulse counter input 2 : +** Peripheral Type LPUART : +** Custom name : LPUART0 +** LPUART0 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Peripheral Type MCG : +** Custom name : MCG +** Peripheral Type MCM : +** Custom name : MCM +** Peripheral Type NV : +** Custom name : FTFA_FlashConfig +** Peripheral Type NVIC : +** Custom name : NVIC +** Peripheral Type OSC : +** Custom name : OSC +** OSC : +** External clock/oscillator input : +** Oscillator output : +** Peripheral Type PDB : +** Custom name : PDB0 +** PDB0 : +** DAC0 trigger : +** DAC1 trigger : +** Trigger input : +** Peripheral Type PIT : +** Custom name : PIT +** Peripheral Type PMC : +** Custom name : PMC +** Peripheral Type PORT : +** Custom name : PORTA +** Custom name : PORTB +** Custom name : PORTC +** Custom name : PORTD +** Custom name : PORTE +** Peripheral Type RCM : +** Custom name : RCM +** RCM : +** Reset input : RESET_b +** Peripheral Type RFSYS : +** Custom name : RFSYS +** Peripheral Type RFVBAT : +** Custom name : RFVBAT +** Peripheral Type RNG : +** Custom name : RNG +** Peripheral Type RTC : +** Custom name : RTC +** RTC : +** Oscillator output : +** 32.768 kHz oscillator input : EXTAL32 +** VBAT power supply : VBAT +** 32.768 kHz oscillator output : XTAL32 +** Peripheral Type SCB : +** Custom name : SystemControl +** Peripheral Type SIM : +** Custom name : SIM +** SIM : +** Clock generation SIM output : +** ERCLK32K clock output : +** SIM XOR input FTM1 channel 1 : +** SIM XOR input FTM2 channel 0 : +** SIM XOR input FTM2 channel 1 : +** Peripheral Type SMC : +** Custom name : SMC +** Peripheral Type SPI : +** Custom name : SPI0 +** SPI0 : +** SPI peripheral chip select(output) 0 or slave select(input): +** Direction : +** PCS1 - Peripheral chip select 1 : +** PCS2 - Peripheral chip select 2 : +** PCS3 - Peripheral chip select 3 : +** PCS4 - Peripheral chip select 4 : +** SIN - Serial data in : +** SCK - Serial clock : +** Direction : +** SOUT - Serial data out : +** Custom name : SPI1 +** SPI1 : +** SPI peripheral chip select(output) 0 or slave select(input): +** Direction : +** PCS1 - Peripheral chip select 1 : +** SIN - Serial data in : +** SCK - Serial clock : +** Direction : +** SOUT - Serial data out : +** Peripheral Type SUPPLY : +** Peripheral Type SysTick : +** Custom name : SysTick +** Peripheral Type TPIU : +** Custom name : TPIU +** Peripheral Type UART : +** Custom name : UART0 +** UART0 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Custom name : UART1 +** UART1 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Custom name : UART2 +** UART2 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Peripheral Type USB : +** Custom name : USB0 +** USB0 : +** CLKIN - Alternate Clock : +** DM - Data minus : USB0_DM +** DP - Data plus : USB0_DP +** SOF - Start of frame : +** Regulator output voltage : VOUT33 +** Unregulated power supply : VREGIN +** Peripheral Type VREF : +** Custom name : VREF +** VREF : +** Voltage reference output : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** Peripheral Type WDOG : +** Custom name : WDOG +** Non-peripheral pins : +** TRACE_SWO : +** NMI : +** Electrical properties : +** Pin 1: ADC1_SE4a/PTE0/CLKOUT32K/SPI1_PCS1/UART1_TX/I2C1_SDA/RTC_CLKOUT: +** Custom name, Signal name : ADC1_SE4a/PTE0/CLKOUT32K/SPI1_PCS1/UART1_TX/I2C1_SDA/RTC_CLKOUT +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 2: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/I2C1_SCL/SPI1_SIN: +** Custom name, Signal name : ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/I2C1_SCL/SPI1_SIN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 3: VDD8 : +** Custom name, Signal name : VDD8 +** Pin 4: VSS9 : +** Custom name, Signal name : VSS9 +** Pin 5: USB0_DP : +** Custom name, Signal name : USB0_DP +** Pin 6: USB0_DM : +** Custom name, Signal name : USB0_DM +** Pin 7: VOUT33 : +** Custom name, Signal name : VOUT33 +** Pin 8: VREGIN : +** Custom name, Signal name : VREGIN +** Pin 9: ADC0_DP0/ADC1_DP3 : +** Custom name, Signal name : ADC0_DP0/ADC1_DP3 +** Pin 10: ADC0_DM0/ADC1_DM3 : +** Custom name, Signal name : ADC0_DM0/ADC1_DM3 +** Pin 11: ADC1_DP0/ADC0_DP3 : +** Custom name, Signal name : ADC1_DP0/ADC0_DP3 +** Pin 12: ADC1_DM0/ADC0_DM3 : +** Custom name, Signal name : ADC1_DM0/ADC0_DM3 +** Pin 13: VDDA : +** Custom name, Signal name : VDDA +** Pin 14: VREFH : +** Custom name, Signal name : VREFH +** Pin 15: VREFL : +** Custom name, Signal name : VREFL +** Pin 16: VSSA : +** Custom name, Signal name : VSSA +** Pin 17: VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18: +** Custom name, Signal name : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** Pin 18: DAC0_OUT/CMP1_IN3/ADC0_SE23 : +** Custom name, Signal name : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** Pin 19: XTAL32 : +** Custom name, Signal name : XTAL32 +** Pin 20: EXTAL32 : +** Custom name, Signal name : EXTAL32 +** Pin 21: VBAT : +** Custom name, Signal name : VBAT +** Pin 22: PTA0/UART0_CTS_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK: +** Custom name, Signal name : PTA0/UART0_CTS_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 23: PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI: +** Custom name, Signal name : PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 24: PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO: +** Custom name, Signal name : PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 25: PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO: +** Custom name, Signal name : PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 26: PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b: +** Custom name, Signal name : PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 27: PTA5/USB_CLKIN/FTM0_CH2/I2S0_TX_BCLK/JTAG_TRST_b: +** Custom name, Signal name : PTA5/USB_CLKIN/FTM0_CH2/I2S0_TX_BCLK/JTAG_TRST_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 28: PTA12/FTM1_CH0/I2S0_TXD0/FTM1_QD_PHA: +** Custom name, Signal name : PTA12/FTM1_CH0/I2S0_TXD0/FTM1_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 29: PTA13/LLWU_P4/FTM1_CH1/I2S0_TX_FS/FTM1_QD_PHB: +** Custom name, Signal name : PTA13/LLWU_P4/FTM1_CH1/I2S0_TX_FS/FTM1_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 30: VDD55 : +** Custom name, Signal name : VDD55 +** Pin 31: VSS56 : +** Custom name, Signal name : VSS56 +** Pin 32: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 : +** Custom name, Signal name : EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 33: XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1: +** Custom name, Signal name : XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 34: RESET_b : +** Custom name, Signal name : RESET_b +** Pin 35: ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/FTM1_QD_PHA: +** Custom name, Signal name : ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/FTM1_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 36: ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/FTM1_QD_PHB: +** Custom name, Signal name : ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/FTM1_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 37: ADC0_SE12/PTB2/I2C0_SCL/UART0_RTS_b/FTM0_FLT3: +** Custom name, Signal name : ADC0_SE12/PTB2/I2C0_SCL/UART0_RTS_b/FTM0_FLT3 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 38: ADC0_SE13/PTB3/I2C0_SDA/UART0_CTS_b/FTM0_FLT0: +** Custom name, Signal name : ADC0_SE13/PTB3/I2C0_SDA/UART0_CTS_b/FTM0_FLT0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 39: PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN: +** Custom name, Signal name : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 40: PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b: +** Custom name, Signal name : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 41: PTB18/FTM2_CH0/I2S0_TX_BCLK/FBa_AD15/FTM2_QD_PHA: +** Custom name, Signal name : PTB18/FTM2_CH0/I2S0_TX_BCLK/FBa_AD15/FTM2_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 42: PTB19/FTM2_CH1/I2S0_TX_FS/FBa_OE_b/FTM2_QD_PHB: +** Custom name, Signal name : PTB19/FTM2_CH1/I2S0_TX_FS/FBa_OE_b/FTM2_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 43: ADC0_SE14/PTC0/SPI0_PCS4/PDB0_EXTRG/USB_SOF_OUT/FBa_AD14: +** Custom name, Signal name : ADC0_SE14/PTC0/SPI0_PCS4/PDB0_EXTRG/USB_SOF_OUT/FBa_AD14 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 44: ADC0_SE15/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/I2S0_TXD0/LPUART0_RTS_b: +** Custom name, Signal name : ADC0_SE15/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/I2S0_TXD0/LPUART0_RTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 45: ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b: +** Custom name, Signal name : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 46: CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX: +** Custom name, Signal name : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 47: VSS85 : +** Custom name, Signal name : VSS85 +** Pin 48: VDD86 : +** Custom name, Signal name : VDD86 +** Pin 49: PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX: +** Custom name, Signal name : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 50: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/CMP0_OUT/FTM0_CH2: +** Custom name, Signal name : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/CMP0_OUT/FTM0_CH2 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 51: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/I2S0_MCLK: +** Custom name, Signal name : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/I2S0_MCLK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 52: CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FBa_AD8: +** Custom name, Signal name : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FBa_AD8 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 53: ADC1_SE4b/CMP0_IN2/PTC8/FTM3_CH4/I2S0_MCLK/FBa_AD7: +** Custom name, Signal name : ADC1_SE4b/CMP0_IN2/PTC8/FTM3_CH4/I2S0_MCLK/FBa_AD7 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 54: ADC1_SE5b/CMP0_IN3/PTC9/FTM3_CH5/I2S0_RX_BCLK/FBa_AD6/FTM2_FLT0: +** Custom name, Signal name : ADC1_SE5b/CMP0_IN3/PTC9/FTM3_CH5/I2S0_RX_BCLK/FBa_AD6/FTM2_FLT0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 55: ADC1_SE6b/PTC10/I2C1_SCL/FTM3_CH6/I2S0_RX_FS/FBa_AD5: +** Custom name, Signal name : ADC1_SE6b/PTC10/I2C1_SCL/FTM3_CH6/I2S0_RX_FS/FBa_AD5 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 56: ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/FTM3_CH7/FBa_RW_b: +** Custom name, Signal name : ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/FTM3_CH7/FBa_RW_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 57: PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FTM3_CH0/FBa_ALE/FBa_CS1_b/FBa_TS_b/LPUART0_RTS_b: +** Custom name, Signal name : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FTM3_CH0/FBa_ALE/FBa_CS1_b/FBa_TS_b/LPUART0_RTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 58: ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b/FTM3_CH1/FBa_CS0_b/LPUART0_CTS_b: +** Custom name, Signal name : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b/FTM3_CH1/FBa_CS0_b/LPUART0_CTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 59: PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FTM3_CH2/FBa_AD4/LPUART0_RX/I2C0_SCL: +** Custom name, Signal name : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FTM3_CH2/FBa_AD4/LPUART0_RX/I2C0_SCL +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 60: PTD3/SPI0_SIN/UART2_TX/FTM3_CH3/FBa_AD3/LPUART0_TX/I2C0_SDA: +** Custom name, Signal name : PTD3/SPI0_SIN/UART2_TX/FTM3_CH3/FBa_AD3/LPUART0_TX/I2C0_SDA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 61: PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/EWM_IN/SPI1_PCS0: +** Custom name, Signal name : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/EWM_IN/SPI1_PCS0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 62: ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/FTM0_CH5/FBa_AD1/EWM_OUT_b/SPI1_SCK: +** Custom name, Signal name : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/FTM0_CH5/FBa_AD1/EWM_OUT_b/SPI1_SCK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 63: ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FBa_AD0/FTM0_FLT0/SPI1_SOUT: +** Custom name, Signal name : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FBa_AD0/FTM0_FLT0/SPI1_SOUT +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 64: PTD7/UART0_TX/FTM0_CH7/FTM0_FLT1/SPI1_SIN: +** Custom name, Signal name : PTD7/UART0_TX/FTM0_CH7/FTM0_FLT1/SPI1_SIN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Pins1.c +** @version 1.1 +** @brief +** +*/ +/*! +** @addtogroup Pins1_module Pins1 module documentation +** @{ +*/ + +/* MODULE Pins1. */ + +#include "Pins1.h" +#include "PE_Types.h" +#include "IO_Map.h" + + + +/* END Pins1. */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.h new file mode 100644 index 0000000..8d9740d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Pins1.h @@ -0,0 +1,995 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Pins1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : PinSettings +** Version : Component 01.100, Driver 1.1, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** +** Settings : +** Component name : Pins1 +** PinSettings IP Block : PinSettings +** Processor : MK22FN512LH12 +** Pin settings : +** Routing : +** Peripheral Type ADC : +** Custom name : ADC0 +** ADC0 : +** DM0 - Minus channel 0 : ADC0_DM0/ADC1_DM3 +** DM3 - Minus channel 3 : ADC1_DM0/ADC0_DM3 +** DM26 - Minus channel 26 : TempSensor_minus +** DM27 - Minus channel 27 : Bandgap_minus +** DM29 - Minus channel 29 : +** DP0 - Plus channel 0 : ADC0_DP0/ADC1_DP3 +** DP3 - Plus channel 3 : ADC1_DP0/ADC0_DP3 +** DP26 - Plus channel 26 : TempSensor_plus +** DP27 - Plus channel 27 : Bandgap_plus +** DP29 - Plus channel 29 : +** SE0 - Single-ended channel 0 : ADC0_DP0/ADC1_DP3 +** SE3 - Single-ended channel 3 : ADC1_DP0/ADC0_DP3 +** SE8 - Single-ended channel 8 : +** SE9 - Single-ended channel 9 : +** SE12 - Single-ended channel 12 : +** SE13 - Single-ended channel 13 : +** SE14 - Single-ended channel 14 : +** SE15 - Single-ended channel 15 : +** SE19 - Single-ended channel 19 : ADC0_DM0/ADC1_DM3 +** SE23 - Single-ended channel 23 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** SE26 - Single-ended channel 26 : TempSensor +** SE27 - Single-ended channel 27 : Bandgap +** SE29 - Single-ended channel 29 : +** SE30 - Single-ended channel 30 : +** SE4b - Single-ended channel 4b : +** SE5b - Single-ended channel 5b : +** SE6b - Single-ended channel 6b : +** SE7b - Single-ended channel 7b : +** Trigger A input : +** Trigger B input : +** Voltage reference high : +** Voltage reference low : +** Custom name : ADC1 +** ADC1 : +** DM0 - Minus channel 0 : ADC1_DM0/ADC0_DM3 +** DM3 - Minus channel 3 : ADC0_DM0/ADC1_DM3 +** DM26 - Minus channel 26 : TempSensor_minus +** DM27 - Minus channel 27 : Bandgap_minus +** DM29 - Minus channel 29 : +** DP0 - Plus channel 0 : ADC1_DP0/ADC0_DP3 +** DP3 - Plus channel 3 : ADC0_DP0/ADC1_DP3 +** DP26 - Plus channel 26 : TempSensor_plus +** DP27 - Plus channel 27 : Bandgap_plus +** DP29 - Plus channel 29 : +** SE0 - Single-ended channel 0 : ADC1_DP0/ADC0_DP3 +** SE3 - Single-ended channel 3 : ADC0_DP0/ADC1_DP3 +** SE8 - Single-ended channel 8 : +** SE9 - Single-ended channel 9 : +** SE18 - Single-ended channel 18 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** SE19 - Single-ended channel 19 : ADC1_DM0/ADC0_DM3 +** SE23 - Single-ended channel 23 : DAC12b1_Output +** SE26 - Single-ended channel 26 : TempSensor +** SE27 - Single-ended channel 27 : Bandgap +** SE29 - Single-ended channel 29 : +** SE30 - Single-ended channel 30 : +** SE4a - Single-ended channel 4a : +** SE5a - Single-ended channel 5a : +** SE4b - Single-ended channel 4b : +** SE5b - Single-ended channel 5b : +** SE6b - Single-ended channel 6b : +** SE7b - Single-ended channel 7b : +** Trigger A input : +** Trigger B input : +** Voltage reference high : +** Voltage reference low : +** Peripheral Type CMP : +** Custom name : CMP0 +** CMP0 : +** IN0 - Negative input 0 : +** IN1 - Negative input 1 : +** IN2 - Negative input 2 : +** IN3 - Negative input 3 : +** IN4 - Negative input 4 : DAC12b1_Output +** IN5 - Negative input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Negative input 6 : Bandgap +** IN7 - Negative input 7 : DAC6b0_Output +** OUT - Comparator output : +** IN0 - Positive input 0 : +** IN1 - Positive input 1 : +** IN2 - Positive input 2 : +** IN3 - Positive input 3 : +** IN4 - Positive input 4 : DAC12b1_Output +** IN5 - Positive input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Positive input 6 : Bandgap +** IN7 - Positive input 7 : DAC6b0_Output +** Window/sample input : PDB0_PulseOut0 +** Custom name : CMP1 +** CMP1 : +** IN0 - Negative input 0 : +** IN1 - Negative input 1 : +** IN3 - Negative input 3 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** IN5 - Negative input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Negative input 6 : Bandgap +** IN7 - Negative input 7 : DAC6b1_Output +** OUT - Comparator output : +** IN0 - Positive input 0 : +** IN1 - Positive input 1 : +** IN3 - Positive input 3 : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** IN5 - Positive input 5 : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** IN6 - Positive input 6 : Bandgap +** IN7 - Positive input 7 : DAC6b1_Output +** Window/sample input : PDB0_PulseOut1 +** Peripheral Type CRC : +** Custom name : CRC +** Peripheral Type CoreDebug : +** Peripheral Type DAC : +** Custom name : DAC0 +** DAC0 : +** Output pin : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** Trigger input : PDB0_DAC0_Trigger +** Custom name : DAC1 +** DAC1 : +** Trigger input : PDB0_DAC1_Trigger +** Peripheral Type DMA : +** Custom name : DMA +** DMA : +** Channel 0 trigger : +** Channel 1 trigger : +** Channel 2 trigger : +** Channel 3 trigger : +** Channel 4 trigger : +** Channel 5 trigger : +** Channel 6 trigger : +** Channel 7 trigger : +** Channel 8 trigger : +** Channel 9 trigger : +** Channel 10 trigger : +** Channel 11 trigger : +** Channel 12 trigger : +** Channel 13 trigger : +** Channel 14 trigger : +** Channel 15 trigger : +** Channel 0 periodic trigger : +** Channel 1 periodic trigger : +** Channel 2 periodic trigger : +** Channel 3 periodic trigger : +** Peripheral Type DMAMUX : +** Custom name : DMAMUX +** Peripheral Type DWT : +** Peripheral Type ETF : +** Peripheral Type ETM : +** Peripheral Type EWM : +** Custom name : EWM +** EWM : +** Input pin : +** Output pin : +** Peripheral Type FB : +** Custom name : FB +** FB : +** AD0 - Address/data bus 0 : +** AD1 - Address/data bus 1 : +** AD2 - Address/data bus 2 : +** AD3 - Address/data bus 3 : +** AD4 - Address/data bus 4 : +** AD5 - Address/data bus 5 : +** AD6 - Address/data bus 6 : +** AD7 - Address/data bus 7 : +** AD8 - Address/data bus 8 : +** AD9 - Address/data bus 9 : +** AD10 - Address/data bus 10 : +** AD11 - Address/data bus 11 : +** AD12 - Address/data bus 12 : +** AD13 - Address/data bus 13 : +** AD14 - Address/data bus 14 : +** AD15 - Address/data bus 15 : +** AD16 - Address/data bus 16 : +** AD17 - Address/data bus 17 : +** ALE - Address latch enable : +** CS0 - Chip select 0 : +** CS1 - Chip select 1 : +** OE - Output enable : +** RW - Read/write : +** TS - Transfer start : +** Peripheral Type FMC : +** Custom name : FMC +** Peripheral Type FPB : +** Peripheral Type FTFA : +** Custom name : FTFA +** Peripheral Type FTM : +** Custom name : FTM0 +** FTM0 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CH2 - Channel 2 : +** Direction : +** CH3 - Channel 3 : +** Direction : +** CH4 - Channel 4 : +** Direction : +** CH5 - Channel 5 : +** Direction : +** CH6 - Channel 6 : +** Direction : +** CH7 - Channel 7 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** FLT2 - Fault input 2 : +** FLT3 - Fault input 3 : +** Trigger input 0 : +** Trigger input 1 : +** Trigger input 2 : +** Custom name : FTM1 +** FTM1 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** Quadrature decoder phase A input : +** Quadrature decoder phase B input : +** Trigger input 0 : +** Trigger input 1 : +** Trigger input 2 : +** Custom name : FTM2 +** FTM2 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** FLT1 - Fault input 1 : +** Quadrature decoder phase A input : +** Quadrature decoder phase B input : +** Trigger input 0 : +** Trigger input 2 : +** Custom name : FTM3 +** FTM3 : +** CH0 - Channel 0 : +** Direction : +** CH1 - Channel 1 : +** Direction : +** CH2 - Channel 2 : +** Direction : +** CH3 - Channel 3 : +** Direction : +** CH4 - Channel 4 : +** Direction : +** CH5 - Channel 5 : +** Direction : +** CH6 - Channel 6 : +** Direction : +** CH7 - Channel 7 : +** Direction : +** CLKIN0 - External clock input : +** FLT0 - Fault input 0 : +** Trigger input 0 : +** Trigger input 1 : +** Peripheral Type GPIO : +** Custom name : PTA +** PTA : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 12 : +** Direction : +** Pin 13 : +** Direction : +** Pin 18 : +** Direction : +** Pin 19 : +** Direction : +** Custom name : PTB +** PTB : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 16 : +** Direction : +** Pin 17 : +** Direction : +** Pin 18 : +** Direction : +** Pin 19 : +** Direction : +** Custom name : PTC +** PTC : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 6 : +** Direction : +** Pin 7 : +** Direction : +** Pin 8 : +** Direction : +** Pin 9 : +** Direction : +** Pin 10 : +** Direction : +** Pin 11 : +** Direction : +** Custom name : PTD +** PTD : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Pin 2 : +** Direction : +** Pin 3 : +** Direction : +** Pin 4 : +** Direction : +** Pin 5 : +** Direction : +** Pin 6 : +** Direction : +** Pin 7 : +** Direction : +** Custom name : PTE +** PTE : +** Pin 0 : +** Direction : +** Pin 1 : +** Direction : +** Peripheral Type I2C : +** Custom name : I2C0 +** I2C0 : +** SCL - Serial clock : +** SDA - Serial data : +** Custom name : I2C1 +** I2C1 : +** SCL - Serial clock : +** SDA - Serial data : +** Peripheral Type I2S : +** Custom name : I2S0 +** I2S0 : +** MCLK - Master clock : +** RX_BCLK - RX bit clock : +** Direction : +** RX_FS - RX frame sync : +** Direction : +** RXD0 - Receive data 0 : +** TX_BCLK - TX bit clock : +** Direction : +** TX_FS - TX frame sync : +** Direction : +** TXD0 - Transmit data 0 : +** Peripheral Type ITM : +** Peripheral Type JTAG : +** JTAG : +** TCLK - Test clock : +** TDI - Test data input : +** TDO - Test data output : +** TMS - Test mode selection : +** TRST - Reset : +** Peripheral Type LLWU : +** Custom name : LLWU +** LLWU : +** P0 - Wake-up pin 0 : +** P3 - Wake-up pin 3 : +** P4 - Wake-up pin 4 : +** P5 - Wake-up pin 5 : +** P6 - Wake-up pin 6 : +** P7 - Wake-up pin 7 : +** P8 - Wake-up pin 8 : +** P9 - Wake-up pin 9 : +** P10 - Wake-up pin 10 : +** P11 - Wake-up pin 11 : +** P12 - Wake-up pin 12 : +** P13 - Wake-up pin 13 : +** P14 - Wake-up pin 14 : +** P15 - Wake-up pin 15 : +** Peripheral Type LPTMR : +** Custom name : LPTMR0 +** LPTMR0 : +** Pulse counter input 0 : +** Pulse counter input 1 : +** Pulse counter input 2 : +** Peripheral Type LPUART : +** Custom name : LPUART0 +** LPUART0 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Peripheral Type MCG : +** Custom name : MCG +** Peripheral Type MCM : +** Custom name : MCM +** Peripheral Type NV : +** Custom name : FTFA_FlashConfig +** Peripheral Type NVIC : +** Custom name : NVIC +** Peripheral Type OSC : +** Custom name : OSC +** OSC : +** External clock/oscillator input : +** Oscillator output : +** Peripheral Type PDB : +** Custom name : PDB0 +** PDB0 : +** DAC0 trigger : +** DAC1 trigger : +** Trigger input : +** Peripheral Type PIT : +** Custom name : PIT +** Peripheral Type PMC : +** Custom name : PMC +** Peripheral Type PORT : +** Custom name : PORTA +** Custom name : PORTB +** Custom name : PORTC +** Custom name : PORTD +** Custom name : PORTE +** Peripheral Type RCM : +** Custom name : RCM +** RCM : +** Reset input : RESET_b +** Peripheral Type RFSYS : +** Custom name : RFSYS +** Peripheral Type RFVBAT : +** Custom name : RFVBAT +** Peripheral Type RNG : +** Custom name : RNG +** Peripheral Type RTC : +** Custom name : RTC +** RTC : +** Oscillator output : +** 32.768 kHz oscillator input : EXTAL32 +** VBAT power supply : VBAT +** 32.768 kHz oscillator output : XTAL32 +** Peripheral Type SCB : +** Custom name : SystemControl +** Peripheral Type SIM : +** Custom name : SIM +** SIM : +** Clock generation SIM output : +** ERCLK32K clock output : +** SIM XOR input FTM1 channel 1 : +** SIM XOR input FTM2 channel 0 : +** SIM XOR input FTM2 channel 1 : +** Peripheral Type SMC : +** Custom name : SMC +** Peripheral Type SPI : +** Custom name : SPI0 +** SPI0 : +** SPI peripheral chip select(output) 0 or slave select(input): +** Direction : +** PCS1 - Peripheral chip select 1 : +** PCS2 - Peripheral chip select 2 : +** PCS3 - Peripheral chip select 3 : +** PCS4 - Peripheral chip select 4 : +** SIN - Serial data in : +** SCK - Serial clock : +** Direction : +** SOUT - Serial data out : +** Custom name : SPI1 +** SPI1 : +** SPI peripheral chip select(output) 0 or slave select(input): +** Direction : +** PCS1 - Peripheral chip select 1 : +** SIN - Serial data in : +** SCK - Serial clock : +** Direction : +** SOUT - Serial data out : +** Peripheral Type SUPPLY : +** Peripheral Type SysTick : +** Custom name : SysTick +** Peripheral Type TPIU : +** Custom name : TPIU +** Peripheral Type UART : +** Custom name : UART0 +** UART0 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Custom name : UART1 +** UART1 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Custom name : UART2 +** UART2 : +** CTS - Clear to send : +** RTS - Request to send : +** RX - Receive data : +** TX - Transmit data : +** Peripheral Type USB : +** Custom name : USB0 +** USB0 : +** CLKIN - Alternate Clock : +** DM - Data minus : USB0_DM +** DP - Data plus : USB0_DP +** SOF - Start of frame : +** Regulator output voltage : VOUT33 +** Unregulated power supply : VREGIN +** Peripheral Type VREF : +** Custom name : VREF +** VREF : +** Voltage reference output : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** Peripheral Type WDOG : +** Custom name : WDOG +** Non-peripheral pins : +** TRACE_SWO : +** NMI : +** Electrical properties : +** Pin 1: ADC1_SE4a/PTE0/CLKOUT32K/SPI1_PCS1/UART1_TX/I2C1_SDA/RTC_CLKOUT: +** Custom name, Signal name : ADC1_SE4a/PTE0/CLKOUT32K/SPI1_PCS1/UART1_TX/I2C1_SDA/RTC_CLKOUT +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 2: ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/I2C1_SCL/SPI1_SIN: +** Custom name, Signal name : ADC1_SE5a/PTE1/LLWU_P0/SPI1_SOUT/UART1_RX/I2C1_SCL/SPI1_SIN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 3: VDD8 : +** Custom name, Signal name : VDD8 +** Pin 4: VSS9 : +** Custom name, Signal name : VSS9 +** Pin 5: USB0_DP : +** Custom name, Signal name : USB0_DP +** Pin 6: USB0_DM : +** Custom name, Signal name : USB0_DM +** Pin 7: VOUT33 : +** Custom name, Signal name : VOUT33 +** Pin 8: VREGIN : +** Custom name, Signal name : VREGIN +** Pin 9: ADC0_DP0/ADC1_DP3 : +** Custom name, Signal name : ADC0_DP0/ADC1_DP3 +** Pin 10: ADC0_DM0/ADC1_DM3 : +** Custom name, Signal name : ADC0_DM0/ADC1_DM3 +** Pin 11: ADC1_DP0/ADC0_DP3 : +** Custom name, Signal name : ADC1_DP0/ADC0_DP3 +** Pin 12: ADC1_DM0/ADC0_DM3 : +** Custom name, Signal name : ADC1_DM0/ADC0_DM3 +** Pin 13: VDDA : +** Custom name, Signal name : VDDA +** Pin 14: VREFH : +** Custom name, Signal name : VREFH +** Pin 15: VREFL : +** Custom name, Signal name : VREFL +** Pin 16: VSSA : +** Custom name, Signal name : VSSA +** Pin 17: VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18: +** Custom name, Signal name : VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 +** Pin 18: DAC0_OUT/CMP1_IN3/ADC0_SE23 : +** Custom name, Signal name : DAC0_OUT/CMP1_IN3/ADC0_SE23 +** Pin 19: XTAL32 : +** Custom name, Signal name : XTAL32 +** Pin 20: EXTAL32 : +** Custom name, Signal name : EXTAL32 +** Pin 21: VBAT : +** Custom name, Signal name : VBAT +** Pin 22: PTA0/UART0_CTS_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK: +** Custom name, Signal name : PTA0/UART0_CTS_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 23: PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI: +** Custom name, Signal name : PTA1/UART0_RX/FTM0_CH6/JTAG_TDI/EZP_DI +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 24: PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO: +** Custom name, Signal name : PTA2/UART0_TX/FTM0_CH7/JTAG_TDO/TRACE_SWO/EZP_DO +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 25: PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO: +** Custom name, Signal name : PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 26: PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b: +** Custom name, Signal name : PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 27: PTA5/USB_CLKIN/FTM0_CH2/I2S0_TX_BCLK/JTAG_TRST_b: +** Custom name, Signal name : PTA5/USB_CLKIN/FTM0_CH2/I2S0_TX_BCLK/JTAG_TRST_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 28: PTA12/FTM1_CH0/I2S0_TXD0/FTM1_QD_PHA: +** Custom name, Signal name : PTA12/FTM1_CH0/I2S0_TXD0/FTM1_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 29: PTA13/LLWU_P4/FTM1_CH1/I2S0_TX_FS/FTM1_QD_PHB: +** Custom name, Signal name : PTA13/LLWU_P4/FTM1_CH1/I2S0_TX_FS/FTM1_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 30: VDD55 : +** Custom name, Signal name : VDD55 +** Pin 31: VSS56 : +** Custom name, Signal name : VSS56 +** Pin 32: EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 : +** Custom name, Signal name : EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 33: XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1: +** Custom name, Signal name : XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 34: RESET_b : +** Custom name, Signal name : RESET_b +** Pin 35: ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/FTM1_QD_PHA: +** Custom name, Signal name : ADC0_SE8/ADC1_SE8/PTB0/LLWU_P5/I2C0_SCL/FTM1_CH0/FTM1_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 36: ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/FTM1_QD_PHB: +** Custom name, Signal name : ADC0_SE9/ADC1_SE9/PTB1/I2C0_SDA/FTM1_CH1/FTM1_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 37: ADC0_SE12/PTB2/I2C0_SCL/UART0_RTS_b/FTM0_FLT3: +** Custom name, Signal name : ADC0_SE12/PTB2/I2C0_SCL/UART0_RTS_b/FTM0_FLT3 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 38: ADC0_SE13/PTB3/I2C0_SDA/UART0_CTS_b/FTM0_FLT0: +** Custom name, Signal name : ADC0_SE13/PTB3/I2C0_SDA/UART0_CTS_b/FTM0_FLT0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 39: PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN: +** Custom name, Signal name : PTB16/SPI1_SOUT/UART0_RX/FTM_CLKIN0/FBa_AD17/EWM_IN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 40: PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b: +** Custom name, Signal name : PTB17/SPI1_SIN/UART0_TX/FTM_CLKIN1/FBa_AD16/EWM_OUT_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 41: PTB18/FTM2_CH0/I2S0_TX_BCLK/FBa_AD15/FTM2_QD_PHA: +** Custom name, Signal name : PTB18/FTM2_CH0/I2S0_TX_BCLK/FBa_AD15/FTM2_QD_PHA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 42: PTB19/FTM2_CH1/I2S0_TX_FS/FBa_OE_b/FTM2_QD_PHB: +** Custom name, Signal name : PTB19/FTM2_CH1/I2S0_TX_FS/FBa_OE_b/FTM2_QD_PHB +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 43: ADC0_SE14/PTC0/SPI0_PCS4/PDB0_EXTRG/USB_SOF_OUT/FBa_AD14: +** Custom name, Signal name : ADC0_SE14/PTC0/SPI0_PCS4/PDB0_EXTRG/USB_SOF_OUT/FBa_AD14 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 44: ADC0_SE15/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/I2S0_TXD0/LPUART0_RTS_b: +** Custom name, Signal name : ADC0_SE15/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/FBa_AD13/I2S0_TXD0/LPUART0_RTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 45: ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b: +** Custom name, Signal name : ADC0_SE4b/CMP1_IN0/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/FBa_AD12/I2S0_TX_FS/LPUART0_CTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 46: CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX: +** Custom name, Signal name : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUT/I2S0_TX_BCLK/LPUART0_RX +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 47: VSS85 : +** Custom name, Signal name : VSS85 +** Pin 48: VDD86 : +** Custom name, Signal name : VDD86 +** Pin 49: PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX: +** Custom name, Signal name : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/FBa_AD11/CMP1_OUT/LPUART0_TX +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 50: PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/CMP0_OUT/FTM0_CH2: +** Custom name, Signal name : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/FBa_AD10/CMP0_OUT/FTM0_CH2 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 51: CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/I2S0_MCLK: +** Custom name, Signal name : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/FBa_AD9/I2S0_MCLK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 52: CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FBa_AD8: +** Custom name, Signal name : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS/FBa_AD8 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 53: ADC1_SE4b/CMP0_IN2/PTC8/FTM3_CH4/I2S0_MCLK/FBa_AD7: +** Custom name, Signal name : ADC1_SE4b/CMP0_IN2/PTC8/FTM3_CH4/I2S0_MCLK/FBa_AD7 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 54: ADC1_SE5b/CMP0_IN3/PTC9/FTM3_CH5/I2S0_RX_BCLK/FBa_AD6/FTM2_FLT0: +** Custom name, Signal name : ADC1_SE5b/CMP0_IN3/PTC9/FTM3_CH5/I2S0_RX_BCLK/FBa_AD6/FTM2_FLT0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 55: ADC1_SE6b/PTC10/I2C1_SCL/FTM3_CH6/I2S0_RX_FS/FBa_AD5: +** Custom name, Signal name : ADC1_SE6b/PTC10/I2C1_SCL/FTM3_CH6/I2S0_RX_FS/FBa_AD5 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 56: ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/FTM3_CH7/FBa_RW_b: +** Custom name, Signal name : ADC1_SE7b/PTC11/LLWU_P11/I2C1_SDA/FTM3_CH7/FBa_RW_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Pin 57: PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FTM3_CH0/FBa_ALE/FBa_CS1_b/FBa_TS_b/LPUART0_RTS_b: +** Custom name, Signal name : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b/FTM3_CH0/FBa_ALE/FBa_CS1_b/FBa_TS_b/LPUART0_RTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 58: ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b/FTM3_CH1/FBa_CS0_b/LPUART0_CTS_b: +** Custom name, Signal name : ADC0_SE5b/PTD1/SPI0_SCK/UART2_CTS_b/FTM3_CH1/FBa_CS0_b/LPUART0_CTS_b +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 59: PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FTM3_CH2/FBa_AD4/LPUART0_RX/I2C0_SCL: +** Custom name, Signal name : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX/FTM3_CH2/FBa_AD4/LPUART0_RX/I2C0_SCL +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 60: PTD3/SPI0_SIN/UART2_TX/FTM3_CH3/FBa_AD3/LPUART0_TX/I2C0_SDA: +** Custom name, Signal name : PTD3/SPI0_SIN/UART2_TX/FTM3_CH3/FBa_AD3/LPUART0_TX/I2C0_SDA +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 61: PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/EWM_IN/SPI1_PCS0: +** Custom name, Signal name : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/FBa_AD2/EWM_IN/SPI1_PCS0 +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 62: ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/FTM0_CH5/FBa_AD1/EWM_OUT_b/SPI1_SCK: +** Custom name, Signal name : ADC0_SE6b/PTD5/SPI0_PCS2/UART0_CTS_b/FTM0_CH5/FBa_AD1/EWM_OUT_b/SPI1_SCK +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 63: ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FBa_AD0/FTM0_FLT0/SPI1_SOUT: +** Custom name, Signal name : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FBa_AD0/FTM0_FLT0/SPI1_SOUT +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Pin 64: PTD7/UART0_TX/FTM0_CH7/FTM0_FLT1/SPI1_SIN: +** Custom name, Signal name : PTD7/UART0_TX/FTM0_CH7/FTM0_FLT1/SPI1_SIN +** Slew rate : +** Open drain : +** Drive strength : +** Passive filter : +** Pull select : +** Pull enable : +** Digital filter : +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Pins1.h +** @version 1.1 +** @brief +** +*/ +/*! +** @addtogroup Pins1_module Pins1 module documentation +** @{ +*/ + +#ifndef Pins1_H_ +#define Pins1_H_ + +/* MODULE Pins1. */ + +/* Including shared modules, which are used in the whole project */ +#include "Init_Config.h" + + + + +/* END Pins1. */ +#endif /* #ifndef __Pins1_H_ */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.c new file mode 100644 index 0000000..2e38ea9 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.c @@ -0,0 +1,327 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTOSCNTRLDD1.c +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : RTOSCNTRLDD1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 60 MHz +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 100 µs +** Interrupt : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file RTOSCNTRLDD1.c +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup RTOSCNTRLDD1_module RTOSCNTRLDD1 module documentation +** @{ +*/ + +/* MODULE RTOSCNTRLDD1. */ + +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + LDD_TEventMask EnEvents; /* Enable/Disable events mask */ + uint32_t Source; /* Current source clock */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} RTOSCNTRLDD1_TDeviceData; + +typedef RTOSCNTRLDD1_TDeviceData *RTOSCNTRLDD1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static RTOSCNTRLDD1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static RTOSCNTRLDD1_TDeviceDataPtr INT_FTM0__BAREBOARD_RTOS_ISRPARAM; + +#define AVAILABLE_EVENTS_MASK (LDD_TEventMask)(LDD_TIMERUNIT_ON_COUNTER_RESTART) + +/* Internal method prototypes */ +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + RTOSCNTRLDD1_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Interrupt vector(s) allocation */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_FTM0__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC6: FTM0=1 */ + SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; + /* FTM0_MODE: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FAULTIE=0,FAULTM=0,CAPTEST=0,PWMSYNC=0,WPDIS=1,INIT=0,FTMEN=0 */ + FTM0_MODE = (FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK); /* Set up mode register */ + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=0,PS=0 */ + FTM0_SC = (FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00)); /* Clear status and control register */ + /* FTM0_CNTIN: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,INIT=0 */ + FTM0_CNTIN = FTM_CNTIN_INIT(0x00); /* Clear counter initial register */ + /* FTM0_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ + FTM0_CNT = FTM_CNT_COUNT(0x00); /* Reset counter register */ + /* FTM0_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C0SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C1SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C2SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C2SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C3SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C3SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C4SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C4SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C5SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C5SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C6SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C6SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C7SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,ICRST=0,DMA=0 */ + FTM0_C7SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0x176F */ + FTM0_MOD = FTM_MOD_MOD(0x176F); /* Set up modulo register */ + DeviceDataPrv->EnEvents = 0x0100U; /* Enable selected events */ + DeviceDataPrv->Source = FTM_PDD_SYSTEM; /* Store clock source */ + /* NVICIP42: PRI42=0x70 */ + NVICIP42 = NVIC_IP_PRI42(0x70); + /* NVICISER1: SETENA|=0x0400 */ + NVICISER1 |= NVIC_ISER_SETENA(0x0400); + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=1,CPWMS=0,CLKS=1,PS=0 */ + FTM0_SC = (FTM_SC_TOIE_MASK | FTM_SC_CLKS(0x01) | FTM_SC_PS(0x00)); /* Set up status and control register */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_RTOSCNTRLDD1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Deinit (component TimerUnit_LDD) +*/ +/*! +** @brief +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupts vectors, etc. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by Init method +*/ +/* ===================================================================*/ +void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr) +{ + RTOSCNTRLDD1_TDeviceData *DeviceDataPrv = (RTOSCNTRLDD1_TDeviceData *)DeviceDataPtr; + + (void)DeviceDataPrv; + FTM_PDD_SelectPrescalerSource(FTM0_BASE_PTR, FTM_PDD_DISABLED); + /* Interrupt vector(s) deallocation */ + /* {FreeRTOS RTOS Adapter} Restore interrupt vector: IVT is static, no code is generated */ + /* Unregistration of the device structure */ + PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_RTOSCNTRLDD1_ID); + /* Deallocation of the device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: Dynamic allocation is simulated, no deallocation code is generated */ +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr) +{ + RTOSCNTRLDD1_TDeviceData *DeviceDataPrv = (RTOSCNTRLDD1_TDeviceData *)DeviceDataPtr; + + FTM_PDD_SelectPrescalerSource(FTM0_BASE_PTR, DeviceDataPrv->Source); /* Enable the device */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Disable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Disables the component - it stops signal generation and +** events calling. The method is not available if the counter +** can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + FTM_PDD_SelectPrescalerSource(FTM0_BASE_PTR, FTM_PDD_DISABLED); + return ERR_OK; +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(RTOSCNTRLDD1_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + RTOSCNTRLDD1_TDeviceDataPtr DeviceDataPrv = INT_FTM0__BAREBOARD_RTOS_ISRPARAM; + + LDD_TEventMask State = 0U; + + if ((FTM_PDD_GetOverflowInterruptFlag(FTM0_BASE_PTR)) != 0U) { /* Is the overflow interrupt flag pending? */ + State |= LDD_TIMERUNIT_ON_COUNTER_RESTART; /* and set mask */ + } + State &= DeviceDataPrv->EnEvents; /* Handle only enabled interrupts */ + if (State & LDD_TIMERUNIT_ON_COUNTER_RESTART) { /* Is the overflow interrupt flag pending? */ + FTM_PDD_ClearOverflowInterruptFlag(FTM0_BASE_PTR); /* Clear flag */ + RTOSCNTRLDD1_OnCounterRestart(DeviceDataPrv->UserDataPtr); /* Invoke OnCounterRestart event */ + } +} + +/* END RTOSCNTRLDD1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.h new file mode 100644 index 0000000..88912d9 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTOSCNTRLDD1.h @@ -0,0 +1,260 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTOSCNTRLDD1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : RTOSCNTRLDD1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 60 MHz +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 100 µs +** Interrupt : Enabled +** Interrupt : INT_FTM0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file RTOSCNTRLDD1.h +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup RTOSCNTRLDD1_module RTOSCNTRLDD1 module documentation +** @{ +*/ + +#ifndef __RTOSCNTRLDD1_H +#define __RTOSCNTRLDD1_H + +/* MODULE RTOSCNTRLDD1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ + +#include "FTM_PDD.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __BWUserType_RTOSCNTRLDD1_TValueType +#define __BWUserType_RTOSCNTRLDD1_TValueType + typedef uint32_t RTOSCNTRLDD1_TValueType ; /* Type for data parameters of methods */ +#endif +#define RTOSCNTRLDD1_CNT_INP_FREQ_U_0 0x03938700UL /* Counter input frequency in Hz */ +#define RTOSCNTRLDD1_CNT_INP_FREQ_R_0 59998800.02399952F /* Counter input frequency in Hz */ +#define RTOSCNTRLDD1_CNT_INP_FREQ_COUNT 0U /* Count of predefined counter input frequencies */ +#define RTOSCNTRLDD1_PERIOD_TICKS 0x1770UL /* Initialization value of period in 'counter ticks' */ +#define RTOSCNTRLDD1_NUMBER_OF_CHANNELS 0x00U /* Count of predefined channels */ +#define RTOSCNTRLDD1_COUNTER_WIDTH 0x10U /* Counter width in bits */ +#define RTOSCNTRLDD1_COUNTER_DIR DIR_UP /* Direction of counting */ +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define RTOSCNTRLDD1_PRPH_BASE_ADDRESS 0x40038000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define RTOSCNTRLDD1_Init_METHOD_ENABLED /*!< Init method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Deinit_METHOD_ENABLED /*!< Deinit method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Enable_METHOD_ENABLED /*!< Enable method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Disable_METHOD_ENABLED /*!< Disable method of the component RTOSCNTRLDD1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define RTOSCNTRLDD1_OnCounterRestart_EVENT_ENABLED /*!< OnCounterRestart event of the component RTOSCNTRLDD1 is enabled (generated) */ + + + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Deinit (component TimerUnit_LDD) +*/ +/*! +** @brief +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupts vectors, etc. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by Init method +*/ +/* ===================================================================*/ +void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Disable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Disables the component - it stops signal generation and +** events calling. The method is not available if the counter +** can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(RTOSCNTRLDD1_Interrupt); + +/* END RTOSCNTRLDD1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __RTOSCNTRLDD1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.c new file mode 100644 index 0000000..908a0f8 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.c @@ -0,0 +1,563 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:34, # CodeGen: 8 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 3 +** Number of Down Channels : 3 +** Max Blocked Interrupt Level : 3 +** Syscalls : yes +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +/* MODULE RTT1. */ + +#include "RTT1.h" +#include "WAIT1.h" + +/* default standard I/O struct */ +CLS1_ConstStdIOType RTT1_stdio = { + (CLS1_StdIO_In_FctType)RTT1_StdIOReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stderr */ + RTT1_StdIOKeyPressed /* if input is not empty */ + }; +uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ +/** +int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ +/** +int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ +/** +unsigned RTT1_WriteString(unsigned BufferIndex, const char* s) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ +/** +dword RTT1_GetKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ +/** +long RTT1_WaitKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ +/** +long RTT1_HasKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ +bool RTT1_StdIOKeyPressed(void) +{ + return RTT1_HasKey()!=0; +} + +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOReadChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + *c = '\0'; + } else { + *c = (uint8_t)res; /* return character */ + } +} + +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOSendChar(uint8_t ch) +{ +#if RTT1_CONFIG_BLOCKING_SEND + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 && RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + int timeoutMs = RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif + + for(;;) { /* will break */ + if (RTT1_Write(0, (const char*)&ch, 1)==1) { /* non blocking send, check that we were able to send */ + break; /* was able to send character, get out of waiting loop */ + } + #if RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + WAIT1_WaitOSms(RTT1_CONFIG_BLOCKING_SEND_WAIT_MS); + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= RTT1_CONFIG_BLOCKING_SEND_WAIT_MS; + #endif + #endif + } /* for */ +#else + (void)RTT1_Write(0, &ch, 1); /* non blocking send, might loose characters */ +#endif +} + +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t RTT1_RecvChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + return ERR_RXEMPTY; + } + *c = (uint8_t)res; /* return character */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ +uint8_t RTT1_SendChar(uint8_t ch) +{ + int res; + + res = SEGGER_RTT_Write(0, (const char*)&ch, 1); + if (res!=1) { + return ERR_TXFULL; /* character not sent? */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ +/** +uint16_t RTT1_GetCharsInRxBuf(void) +{ + // Function is implemented as macro in the header file + if (SEGGER_RTT_HasKey()) { + return 1; // at least one available + } + return 0; // none available +} +*/ + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_TerminalOut(char TerminalId, const char* s) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_SetTerminal(char TerminalId) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Deinit(void) +{ + /* noting to de-initialize */ +} + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Init(void) +{ + SEGGER_RTT_Init(); +} + +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void) +{ + return &RTT1_stdio; +} + +/* END RTT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.h new file mode 100644 index 0000000..22a8597 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1.h @@ -0,0 +1,476 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 3 +** Number of Down Channels : 3 +** Max Blocked Interrupt Level : 3 +** Syscalls : yes +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +#ifndef __RTT1_H +#define __RTT1_H + +/* MODULE RTT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +/* Include inherited components */ +#include "WAIT1.h" +#include "MCUC1.h" +#include "CLS1.h" + + +#include "SEGGER_RTT.h" + + +#define RTT1_RTT_CHANNEL_0_ENABLED 1 /* 0: channel disabled, 1: channel enabled */ + +extern uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +extern CLS1_ConstStdIOType RTT1_stdio; /* default standard I/O */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTT1_Read(BufferIndex, pBuffer, NumBytes) \ + SEGGER_RTT_Read(BufferIndex, pBuffer, NumBytes) + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ + +#define RTT1_Write(BufferIndex, pBuffer, BufferSize) \ + SEGGER_RTT_Write(BufferIndex, pBuffer, BufferSize) + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ + +#define RTT1_WriteString(BufferIndex, s) \ + SEGGER_RTT_WriteString(BufferIndex, s) + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ + +#define RTT1_GetKey() \ + SEGGER_RTT_GetKey() + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ + +#define RTT1_WaitKey() \ + SEGGER_RTT_WaitKey() + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ + +#define RTT1_HasKey() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ + +bool RTT1_StdIOKeyPressed(void); +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ + +void RTT1_StdIOReadChar(uint8_t *c); +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ + +void RTT1_StdIOSendChar(uint8_t ch); +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ + +uint8_t RTT1_RecvChar(uint8_t *c); +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t RTT1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ + +#define RTT1_GetCharsInRxBuf() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ + +void RTT1_Init(void); + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define RTT1_TerminalOut(TerminalId, s) \ + SEGGER_RTT_TerminalOut(TerminalId, s) + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_SetTerminal(TerminalId) \ + SEGGER_RTT_SetTerminal(TerminalId) + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_printf \ + SEGGER_RTT_printf + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ + +void RTT1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END RTT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __RTT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1config.h new file mode 100644 index 0000000..ebbaf2f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT1config.h @@ -0,0 +1,56 @@ +/** + * \file + * \brief Configuration header file for Segger RTT + * + * This header file is used to configure settings of the Segger RTT Module. + */ + +#ifndef __RTT1_CONFIG_H +#define __RTT1_CONFIG_H + +#ifndef RTT1_CONFIG_PROVIDE_SYSCALLS + #define RTT1_CONFIG_PROVIDE_SYSCALLS (1) + /*!< 1: RTT library implements SysCalls; 0: no Syscalls implemented */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND + #define RTT1_CONFIG_BLOCKING_SEND (1) + /*!< 1: using blocking call for stdio calls; 0: do not using blocking calls */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (5) + /*!< Timeout value for blocking calls for sending. Use zero for no timeout */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_WAIT_MS + #define RTT1_CONFIG_BLOCKING_SEND_WAIT_MS (1) + /*!< Waiting time during blocking send. Use zero for no waiting time */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_UP + #define RTT1_CONFIG_RTT_BUFFER_SIZE_UP (512) + /*!< Size of the up (Tx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN + #define RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN (64) + /*!< Size of the down (Rx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF + #define RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF (64) + /*!< Size of the buffer for RTT printf() in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_UP_BUFFER_MODE + #define RTT1_CONFIG_RTT_UP_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#ifndef RTT1_CONFIG_RTT_DOWN_BUFFER_MODE + #define RTT1_CONFIG_RTT_DOWN_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#endif /* __RTT1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT_Syscalls_GCC.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT_Syscalls_GCC.c new file mode 100644 index 0000000..9ebed3e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/RTT_Syscalls_GCC.c @@ -0,0 +1,203 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) + +#if 0 /* << EST moved to below */ +#include // required for _write_r +#endif +#include "SEGGER_RTT.h" + +#if RTT1_CONFIG_PROVIDE_SYSCALLS /* << EST */ +#include /* for EOF */ /* << EST */ +#include // required for _write_r // << EST moved from above + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +#if 0 +int _write(int file, char *ptr, int len); +int _write_r(struct _reent *r, int file, const void *ptr, int len); +#else /* << EST */ +extern int _write(int file, char *ptr, int len); +extern _ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); +#endif + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +int _write(int file, char *ptr, int len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +#if 0 +int _write_r(struct _reent *r, int file, const void *ptr, int len) { +#else /* << EST */ +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) { +#endif + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +int _putc(int c, __FILE *fp) { /* << EST */ + char ch = c; + (void)fp; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _putchar(int c) { /* << EST */ + char ch = c; + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _getc(__FILE *fp) { /* << EST */ + char ch; + (void)fp; /* Not used, avoid warning */ + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return ch; +} + +int _read(void) { + uint8_t ch; + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return (int)ch; +} + +int __attribute__((weak)) _isatty(int file __attribute__((unused))) { + return 1; +} + +int __attribute__((weak)) _close(int fildes __attribute__((unused))) { + return -1; +} + +int __attribute__((weak)) _lseek(int file __attribute__((unused)), int ptr __attribute__((unused)), int dir __attribute__((unused))) { + return -1; +} + +#if 0 +int __attribute__((weak)) _fstat (int fd __attribute__((unused)), struct stat *st) +{ + memset (st, 0, sizeof(*st)); + st->st_mode = S_IFCHR; + return 0; +} +#endif + + +#endif /* RTT1_CONFIG_PROVIDE_SYSCALLS */ /* << EST */ + +#endif +/****** End Of File *************************************************/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Rx1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Rx1.c new file mode 100644 index 0000000..e579a21 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Rx1.c @@ -0,0 +1,437 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Rx1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : RingBuffer +** Version : Component 01.053, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** This component implements a ring buffer for different integer data type. +** Settings : +** Component name : Rx1 +** Buffer Size : 64 +** Contents : +** Clear - void Rx1_Clear(void); +** Put - uint8_t Rx1_Put(Rx1_ElementType elem); +** Get - uint8_t Rx1_Get(Rx1_ElementType *elemP); +** Peek - uint8_t Rx1_Peek(Rx1_BufSizeType index, Rx1_ElementType *elemP); +** Update - uint8_t Rx1_Update(Rx1_BufSizeType index, Rx1_ElementType *elemP); +** Putn - uint8_t Rx1_Putn(Rx1_ElementType *elem, Rx1_BufSizeType nof); +** Getn - uint8_t Rx1_Getn(Rx1_ElementType *buf, Rx1_BufSizeType nof); +** Compare - uint8_t Rx1_Compare(Rx1_BufSizeType index, Rx1_ElementType *elemP,... +** Delete - uint8_t Rx1_Delete(void); +** NofElements - Rx1_BufSizeType Rx1_NofElements(void); +** NofFreeElements - Rx1_BufSizeType Rx1_NofFreeElements(void); +** Deinit - void Rx1_Deinit(void); +** Init - void Rx1_Init(void); +** +** * Copyright (c) 2014-2018, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file Rx1.h +** @version 01.00 +** @brief +** This component implements a ring buffer for different integer data type. +*/ +/*! +** @addtogroup Rx1_module Rx1 module documentation +** @{ +*/ + +/* MODULE Rx1. */ + +#include "Rx1.h" + +#if Rx1_CONFIG_REENTRANT + #define Rx1_DEFINE_CRITICAL() CS1_CriticalVariable() + #define Rx1_ENTER_CRITICAL() CS1_EnterCritical() + #define Rx1_EXIT_CRITICAL() CS1_ExitCritical() +#else + #define Rx1_DEFINE_CRITICAL() /* nothing */ + #define Rx1_ENTER_CRITICAL() /* nothing */ + #define Rx1_EXIT_CRITICAL() /* nothing */ +#endif +static Rx1_ElementType Rx1_buffer[Rx1_CONFIG_BUF_SIZE]; /* ring buffer */ +static Rx1_BufSizeType Rx1_inIdx; /* input index */ +static Rx1_BufSizeType Rx1_outIdx; /* output index */ +static Rx1_BufSizeType Rx1_inSize; /* size data in buffer */ +/* +** =================================================================== +** Method : Put (component RingBuffer) +** +** Description : +** Puts a new element into the buffer +** Parameters : +** NAME - DESCRIPTION +** elem - New element to be put into the buffer +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Put(Rx1_ElementType elem) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==Rx1_CONFIG_BUF_SIZE) { + res = ERR_TXFULL; + } else { + Rx1_buffer[Rx1_inIdx] = elem; + Rx1_inIdx++; + if (Rx1_inIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_inIdx = 0; + } + Rx1_inSize++; + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Putn (component RingBuffer) +** +** Description : +** Put a number new element into the buffer. +** Parameters : +** NAME - DESCRIPTION +** * elem - Pointer to new elements to be put into +** the buffer +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Putn(Rx1_ElementType *elem, Rx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Rx1_Put(*elem); + if (res!=ERR_OK) { + break; + } + elem++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : Get (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : +** NAME - DESCRIPTION +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Get(Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + *elemP = Rx1_buffer[Rx1_outIdx]; + Rx1_inSize--; + Rx1_outIdx++; + if (Rx1_outIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_outIdx = 0; + } + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Getn (component RingBuffer) +** +** Description : +** Get a number elements into a buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer where to store the +** elements +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Getn(Rx1_ElementType *buf, Rx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Rx1_Get(buf); + if (res!=ERR_OK) { + break; + } + buf++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : NofElements (component RingBuffer) +** +** Description : +** Returns the actual number of elements in the buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Rx1_BufSizeType Rx1_NofElements(void) +{ + return Rx1_inSize; +} + +/* +** =================================================================== +** Method : NofFreeElements (component RingBuffer) +** +** Description : +** Returns the actual number of free elements/space in the +** buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Rx1_BufSizeType Rx1_NofFreeElements(void) +{ + return (Rx1_BufSizeType)(Rx1_CONFIG_BUF_SIZE-Rx1_inSize); +} + +/* +** =================================================================== +** Method : Init (component RingBuffer) +** +** Description : +** Initializes the data structure +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Rx1_Init(void) +{ + Rx1_inIdx = 0; + Rx1_outIdx = 0; + Rx1_inSize = 0; +} + +/* +** =================================================================== +** Method : Clear (component RingBuffer) +** +** Description : +** Clear (empty) the ring buffer. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Rx1_Clear(void) +{ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + Rx1_Init(); + Rx1_EXIT_CRITICAL(); +} + +/* +** =================================================================== +** Method : Peek (component RingBuffer) +** +** Description : +** Returns an element of the buffer without removiing it. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Peek(Rx1_BufSizeType index, Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (index>=Rx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index0) { + res = Rx1_Peek(index, &val); + if (res!=ERR_OK) { /* general failure? */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + if (val!=*elemP) { /* mismatch */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + elemP++; index++; nof--; + } + + return cmpResult; +} + +/* +** =================================================================== +** Method : Deinit (component RingBuffer) +** +** Description : +** Driver de-initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void Rx1_Deinit(void) +{ + ** Function is implemented as macro in the header file +} +*/ +/* +** =================================================================== +** Method : Delete (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Delete(void) +{ + uint8_t res = ERR_OK; + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (Rx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + Rx1_inSize--; + Rx1_outIdx++; + if (Rx1_outIdx==Rx1_CONFIG_BUF_SIZE) { + Rx1_outIdx = 0; + } + } + Rx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Update (component RingBuffer) +** +** Description : +** Updates the data of an element. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Rx1_Update(Rx1_BufSizeType index, Rx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Rx1_DEFINE_CRITICAL(); + + Rx1_ENTER_CRITICAL(); + if (index>=Rx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (indexT Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; +#if 1 /* << EST */ + p->aUp[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_UP; +#else + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; +#if 1 /* << EST */ + p->aDown[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_DOWN; +#else + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + const char* pSrc; +#endif + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytes -= Rem; + WrOff = NumBytes; + do { + *pDst++ = *pData++; + } while (--Rem); + pDst = pRing->pBuffer; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, Rem); + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; +#endif + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFu; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +#if 1 /* << EST: extra function */ +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex) { /* << EST */ + unsigned int avail; + + INIT(); + SEGGER_RTT_LOCK(); + avail = _GetAvailWriteSpace(&_SEGGER_RTT.aUp[bufferIndex]); + SEGGER_RTT_UNLOCK(); + return avail; +} +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT.h new file mode 100644 index 0000000..bfe4fbf --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT.h @@ -0,0 +1,257 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 10533 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex); /* << EST */ +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); + +int SEGGER_printf(const char * sFormat, ...); /* << EST */ + +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_Conf.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..d6b4f4a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_Conf.h @@ -0,0 +1,355 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 9599 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +/* << EST: Additional setting to check for FreeRTOS: need to use FreeRTOS with proper BASEPRI mask to create critical sections */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +#if MCUC1_CONFIG_SDK_USE_FREERTOS + #include "portmacro.h" /* include FreeRTOS port header file for critical section handling */ +#endif + +/* Channel 0 settings from properties */ /* << EST */ +#define SEGGER_RTT_CHANNEL_0_ENABLED (1) /* 1: initialize channel; 0: do not initialize channel */ +#define SEGGER_RTT_CHANNEL_0_NAME "Terminal" +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) +#define SEGGER_RTT_CHANNEL_0_MODE_UP SEGGER_RTT_MODE_NO_BLOCK_SKIP +#define SEGGER_RTT_CHANNEL_0_MODE_DOWN SEGGER_RTT_MODE_NO_BLOCK_SKIP + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (3) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (3) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + /* >> EST */ + #if SEGGER_RTT_FREERTOS_PRESENT + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY /* Interrupts at this level and below will be blocked (valid values 1-15) */ + #else + #define SEGGER_RTT_LOCK_INTERRUPT_LEVEL 3 /* Interrupts at this level and below will be blocked (valid values 1-15 for Kinetis) */ + #define SEGGER_RTT_PRIO_BITS 4 /* NXP Kinetis M4(F) has 4 interrupt priority bits */ + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY (SEGGER_RTT_LOCK_INTERRUPT_LEVEL<<(8-SEGGER_RTT_PRIO_BITS)) + #endif + /* >> EST */ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY) /* input */\ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = OS_GetBASEPRI(); \ + OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_printf.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_printf.c new file mode 100644 index 0000000..bc2f57f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/SEGGER_RTT_printf.c @@ -0,0 +1,563 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } +#if 0 + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; +#else /* << EST: Do not count the characters twice! */ + BufferDesc.ReturnValue = (int)BufferDesc.Cnt; +#endif + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} + +#if 0 /* << EST extension to support extra format characters like %f */ +#include "McuXFormat.h" +#include "McuWait.h" + +int SEGGER_printf(const char * sFormat, ...) { + static char buffer[256]; /* NOT reentrant! */ + va_list args; + int res; + unsigned int avail; + + va_start(args, sFormat); + res = xsnprintf(buffer, sizeof(buffer), sFormat, args); + va_end(args); + if (res > 0) { + int retry = 5; + + do { + /* res is the number of characters written */ + avail = SEGGER_RTT_GetUpBufferFreeSize(0); + if (avail>res) { + break; /* enough space available */ + } else { + McuWait_Waitms(50); + retry--; + } + } while(retry>0); + return SEGGER_RTT_printf(0, "%s", buffer); + } + return -1; /* failed */ +} +#else +int SEGGER_printf(const char * sFormat, ...) { + va_list ParamList; + int res; + + va_start(ParamList, sFormat); + res = SEGGER_RTT_vprintf(0, sFormat, &ParamList); + va_end(ParamList); + return res; +} +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/TMOUT1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/TMOUT1.c new file mode 100644 index 0000000..7cee422 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/TMOUT1.c @@ -0,0 +1,284 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TMOUT1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Timeout +** Version : Component 01.037, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** +The module implements timeout functionality. With this implementation, +it is possible to wait for a given time, and the time is counted by +a periodic interrupt. +** Settings : +** Component name : TMOUT1 +** Maximum counters : 2 +** Counter tick period (ms) : 10 +** RTOS : Enabled +** RTOS : FRTOS1 +** Contents : +** GetCounter - TMOUT1_CounterHandle TMOUT1_GetCounter(TMOUT1_CounterType nofTicks); +** LeaveCounter - void TMOUT1_LeaveCounter(TMOUT1_CounterHandle handle); +** Value - TMOUT1_CounterType TMOUT1_Value(TMOUT1_CounterHandle handle); +** SetCounter - TMOUT1_CounterType TMOUT1_SetCounter(TMOUT1_CounterHandle handle,... +** CounterExpired - bool TMOUT1_CounterExpired(TMOUT1_CounterHandle handle); +** AddTick - void TMOUT1_AddTick(void); +** Init - void TMOUT1_Init(void); +** +** * Copyright (c) 2011-2016, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file TMOUT1.h +** @version 01.00 +** @brief +** +The module implements timeout functionality. With this implementation, +it is possible to wait for a given time, and the time is counted by +a periodic interrupt. +*/ +/*! +** @addtogroup TMOUT1_module TMOUT1 module documentation +** @{ +*/ + +/* MODULE TMOUT1. */ + +#include "TMOUT1.h" + +#define TMOUT1_NOF_COUNTERS 2 /* number of timeout counters available */ + +static TMOUT1_CounterType TMOUT1_Counters[TMOUT1_NOF_COUNTERS]; /* array of timeout counters */ +static bool TMOUT1_FreeCounters[TMOUT1_NOF_COUNTERS]; /* array to indicate which counters are free */ + +/* +** =================================================================== +** Method : GetCounter (component Timeout) +** +** Description : +** Initializes a new timeout counter and returns the handle to +** it. At the end, use LeaveCounter() to free up the resource. +** Parameters : +** NAME - DESCRIPTION +** nofTicks - Number of ticks for the counter +** until it expires. +** Returns : +** --- - Handle to the counter, to be used for +** further API calls. +** =================================================================== +*/ +TMOUT1_CounterHandle TMOUT1_GetCounter(TMOUT1_CounterType nofTicks) +{ + TMOUT1_CounterHandle handle; + CS1_CriticalVariable(); + + handle = 0; + if (nofTicks==0) { + nofTicks = 1; /* wait at least for one tick, otherwise will timeout immediately */ + } + CS1_EnterCritical(); + while (handle0) { + TMOUT1_Counters[i]--; + } + } + CS1_ExitCritical(); +} + +/* +** =================================================================== +** Method : Init (component Timeout) +** +** Description : +** Initialization of the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void TMOUT1_Init(void) +{ + uint8_t i; + + for(i=0;i0) { + res = Tx1_Put(*elem); + if (res!=ERR_OK) { + break; + } + elem++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : Get (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : +** NAME - DESCRIPTION +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Get(Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (Tx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + *elemP = Tx1_buffer[Tx1_outIdx]; + Tx1_inSize--; + Tx1_outIdx++; + if (Tx1_outIdx==Tx1_CONFIG_BUF_SIZE) { + Tx1_outIdx = 0; + } + } + Tx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Getn (component RingBuffer) +** +** Description : +** Get a number elements into a buffer. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer where to store the +** elements +** nof - number of elements +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Getn(Tx1_ElementType *buf, Tx1_BufSizeType nof) +{ + uint8_t res = ERR_OK; + + while(nof>0) { + res = Tx1_Get(buf); + if (res!=ERR_OK) { + break; + } + buf++; nof--; + } + return res; +} + +/* +** =================================================================== +** Method : NofElements (component RingBuffer) +** +** Description : +** Returns the actual number of elements in the buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Tx1_BufSizeType Tx1_NofElements(void) +{ + return Tx1_inSize; +} + +/* +** =================================================================== +** Method : NofFreeElements (component RingBuffer) +** +** Description : +** Returns the actual number of free elements/space in the +** buffer. +** Parameters : None +** Returns : +** --- - Number of elements in the buffer. +** =================================================================== +*/ +Tx1_BufSizeType Tx1_NofFreeElements(void) +{ + return (Tx1_BufSizeType)(Tx1_CONFIG_BUF_SIZE-Tx1_inSize); +} + +/* +** =================================================================== +** Method : Init (component RingBuffer) +** +** Description : +** Initializes the data structure +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Tx1_Init(void) +{ + Tx1_inIdx = 0; + Tx1_outIdx = 0; + Tx1_inSize = 0; +} + +/* +** =================================================================== +** Method : Clear (component RingBuffer) +** +** Description : +** Clear (empty) the ring buffer. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void Tx1_Clear(void) +{ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + Tx1_Init(); + Tx1_EXIT_CRITICAL(); +} + +/* +** =================================================================== +** Method : Peek (component RingBuffer) +** +** Description : +** Returns an element of the buffer without removiing it. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Peek(Tx1_BufSizeType index, Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (index>=Tx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index0) { + res = Tx1_Peek(index, &val); + if (res!=ERR_OK) { /* general failure? */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + if (val!=*elemP) { /* mismatch */ + cmpResult = (uint8_t)-1; /* no match */ + break; + } + elemP++; index++; nof--; + } + + return cmpResult; +} + +/* +** =================================================================== +** Method : Deinit (component RingBuffer) +** +** Description : +** Driver de-initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void Tx1_Deinit(void) +{ + ** Function is implemented as macro in the header file +} +*/ +/* +** =================================================================== +** Method : Delete (component RingBuffer) +** +** Description : +** Removes an element from the buffer +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Delete(void) +{ + uint8_t res = ERR_OK; + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (Tx1_inSize==0) { + res = ERR_RXEMPTY; + } else { + Tx1_inSize--; + Tx1_outIdx++; + if (Tx1_outIdx==Tx1_CONFIG_BUF_SIZE) { + Tx1_outIdx = 0; + } + } + Tx1_EXIT_CRITICAL(); + return res; +} + +/* +** =================================================================== +** Method : Update (component RingBuffer) +** +** Description : +** Updates the data of an element. +** Parameters : +** NAME - DESCRIPTION +** index - Index of element. 0 peeks the top +** element, 1 the next, and so on. +** * elemP - Pointer to where to store the received +** element +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t Tx1_Update(Tx1_BufSizeType index, Tx1_ElementType *elemP) +{ + uint8_t res = ERR_OK; + int idx; /* index inside ring buffer */ + Tx1_DEFINE_CRITICAL(); + + Tx1_ENTER_CRITICAL(); + if (index>=Tx1_CONFIG_BUF_SIZE) { + res = ERR_OVERFLOW; /* asking for an element outside of ring buffer size */ + } else if (index> 0x08) & 0xFEU) +#define USB0_BDTPAGE2_VALUE (uint8_t)((((uint32_t)((uint32_t)&g_Mem[0])) >> 0x10) & 0xFFU) +#define USB0_BDTPAGE3_VALUE (uint8_t)((((uint32_t)((uint32_t)&g_Mem[0])) >> 0x18) & 0xFFU) +/* USB0_SOFTHLD: CNT=0 */ +#define USB0_SOFTHLD_VALUE 0x00U +/* USB0_OTGCTL: DPHIGH=0,??=0,DPLOW=0,DMLOW=0,??=0,OTGEN=0,??=0,??=0 */ +#define USB0_OTGCTL_VALUE 0x00U +/* USB0_CONTROL: ??=0,??=0,??=0,DPPULLUPNONOTG=0,??=0,??=0,??=0,??=0 */ +#define USB0_CONTROL_VALUE 0x00U +/* USB0_CTL: TXSUSPENDTOKENBUSY=0,HOSTMODEEN=0,ODDRST=0,USBENSOFEN=1 */ +#define USB0_CTL_VALUE_2 0x01U +#define USB0_CTL_MASK_2 0x2BU + +#define USB0_AUTOINIT + +#define INT_USB0_ISR USB_ISR + +/* END USB0. */ +#endif /* #ifndef __USB0_Config_H_ */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.c new file mode 100644 index 0000000..f93320e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.c @@ -0,0 +1,178 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : USB1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FSL_USB_Stack +** Version : Component 01.054, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** This component implements a wrapper to the FSL USB Stack. +** Settings : +** Component name : USB1 +** Freescale USB Stack Version : v4.1.1 +** SDK : MCUC1 +** Device Class : CDC Device +** CDC Device : Enabled +** CDCDevice : FSL_USB_CDC_Device +** CDC Host : Disabled +** HID Keyboard Device : Disabled +** HID Joystick Device : Disabled +** HID Mouse Device : Disabled +** MSD Device : Disabled +** MSD Host : Disabled +** Initialization : +** Init USB Function : USB0_Init +** Inherited USB Init : Enabled +** USB Init : Init_USB_OTG_VAR0 +** Initialization : +** Use USB Stack Inititalization : yes +** Call Init Method : yes +** Contents : +** Deinit - uint8_t USB1_Deinit(void); +** Init - uint8_t USB1_Init(void); +** +** * Original USB Stack: (c) Copyright Freescale, all rights reserved, 2013-2015. +** * See separate licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file USB1.h +** @version 01.00 +** @brief +** This component implements a wrapper to the FSL USB Stack. +*/ +/*! +** @addtogroup USB1_module USB1 module documentation +** @{ +*/ + +/* MODULE USB1. */ + +#include "USB1.h" +#include "derivative.h" /* include peripheral declarations */ +#include "types.h" /* Contains User Defined Data Types */ + +/* +** =================================================================== +** Method : USB1_usb_int_dis (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void USB1_usb_int_dis(void) +{ + /* Kinetis K22FN120 */ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + NVIC_DisableIRQ(USB0_IRQn); +#else + NVICISER1 = (1<<21); /* Disable interrupts from USB module (Interrupt Clear-Enable Register) */ +#endif +} + +/* +** =================================================================== +** Method : USB1_usb_int_en (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void USB1_usb_int_en(void) +{ + /* Kinetis K22FN120 */ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + NVIC_ClearPendingIRQ(USB0_IRQn); + NVIC_EnableIRQ(USB0_IRQn); +#else + NVICICPR1 = (1<<21); /* Clear any pending interrupts on USB (Interrupt Clear-Pending Register) */ + NVICISER1 = (1<<21); /* Enable interrupts from USB module (Interrupt Set-Enable Register) */ +#endif +} + +/* +** =================================================================== +** Method : Deinit (component FSL_USB_Stack) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t USB1_Deinit(void) +{ + uint8_t err; + + USB1_usb_int_dis(); /* disable USB interrupts */ + /* Initialize the USB interface */ + err = CDC1_Deinit(); + if(err != ERR_OK) { + /* Error deinitializing USB Class */ + return ERR_FAILED; + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : Init (component FSL_USB_Stack) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t USB1_Init(void) +{ + uint8_t err; + + #if 0 /* not needed with KDS V2.0.0? But needed for K64F */ + MPU_CESR = 0; /* K22FN (Kinetis K2) has memory protection unit, disable it! */ + #endif + /* Initialize the USB interface */ + err = CDC1_Init(); + if(err != ERR_OK) { + /* Error initializing USB Class */ + return ERR_FAILED; + } + USB1_usb_int_en(); + return ERR_OK; +} + +/* END USB1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.h new file mode 100644 index 0000000..f9a2ac6 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1.h @@ -0,0 +1,168 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : USB1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : FSL_USB_Stack +** Version : Component 01.054, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** This component implements a wrapper to the FSL USB Stack. +** Settings : +** Component name : USB1 +** Freescale USB Stack Version : v4.1.1 +** SDK : MCUC1 +** Device Class : CDC Device +** CDC Device : Enabled +** CDCDevice : FSL_USB_CDC_Device +** CDC Host : Disabled +** HID Keyboard Device : Disabled +** HID Joystick Device : Disabled +** HID Mouse Device : Disabled +** MSD Device : Disabled +** MSD Host : Disabled +** Initialization : +** Init USB Function : USB0_Init +** Inherited USB Init : Enabled +** USB Init : Init_USB_OTG_VAR0 +** Initialization : +** Use USB Stack Inititalization : yes +** Call Init Method : yes +** Contents : +** Deinit - uint8_t USB1_Deinit(void); +** Init - uint8_t USB1_Init(void); +** +** * Original USB Stack: (c) Copyright Freescale, all rights reserved, 2013-2015. +** * See separate licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file USB1.h +** @version 01.00 +** @brief +** This component implements a wrapper to the FSL USB Stack. +*/ +/*! +** @addtogroup USB1_module USB1 module documentation +** @{ +*/ + +#ifndef __USB1_H +#define __USB1_H + +/* MODULE USB1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "USB1config.h" /* configuration */ + +/* Include inherited components */ +#include "MCUC1.h" +#include "CDC1.h" + +#include /* for size_t */ + +/* Interfaces/wrappers to the CDC device class, needed for Shell if using default serial/connection to USB (CDC): */ +#define USB1_SendString CDC1_SendString +#define USB1_RecvChar CDC1_GetChar +#define USB1_SendChar CDC1_SendChar +#define USB1_GetCharsInRxBuf CDC1_GetCharsInRxBuf +#define USB1_DATA_BUFF_SIZE CDC1_DATA_BUFF_SIZE /* data buffer size as specified in the properties */ + + +#include "Cpu.h" + + +#ifndef __BWUserType_USB1_TComData +#define __BWUserType_USB1_TComData + typedef uint8_t USB1_TComData ; /* User type for communication data type. */ +#endif + + +#define USB1_USB_ERR_SEND 1 /* Error while sending */ +#define USB1_USB_ERR_BUSOFF 2 /* Bus not ready */ +#define USB1_USB_ERR_INIT 3 /* USB initialization error */ +#define USB1_USB_ERR_TX_CHAR 4 /* Error sending character */ +#define USB1_USB_ERR_TX_STRING 5 /* Error sending string */ +#define USB1_USB_ERR_CHECKED_TXFULL 6 /* Error during sending a checked block */ +#define USB1_USB_ERR_RECEIVE 7 /* Error while starting a receive transaction */ +#define USB1_USB_ERR_DEINIT 8 /* USB deinitialization error */ + +uint8_t USB1_Init(void); +/* +** =================================================================== +** Method : Init (component FSL_USB_Stack) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +void USB1_usb_int_dis(void); +/* +** =================================================================== +** Method : USB1_usb_int_dis (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void USB1_usb_int_en(void); +/* +** =================================================================== +** Method : USB1_usb_int_en (component FSL_USB_Stack) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +uint8_t USB1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FSL_USB_Stack) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END USB1. */ + +#endif +/* ifndef __USB1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1config.h new file mode 100644 index 0000000..69f372b --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB1config.h @@ -0,0 +1,7 @@ +#ifndef __USB1_CONFIG_H +#define __USB1_CONFIG_H + +/* no configuration supported yet */ + +#endif /* __USB1_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB_Config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB_Config.h new file mode 100644 index 0000000..aa45428 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/USB_Config.h @@ -0,0 +1,211 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file USB_Config.h + * + * @author B14088 + * + * @version + * + * @date Oct 31, 2010 + * + * @brief + *****************************************************************************/ + +#ifndef USB_CONFIG_H_ +#define USB_CONFIG_H_ + +/*****************************************************************************/ +/* Includes Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Typedef Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Function's Prototypes */ +/*****************************************************************************/ +/* CDC class services */ +extern void USB_Class_CDC_Service_Dic_Bulk_In (PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_Class_CDC_Service_Dic_Bulk_Out(PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_Class_CDC_Service_Cic_Notify(PTR_USB_DEV_EVENT_STRUCT event); +extern void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event); + +/*****************************************************************************/ +/* Defines & Macros Section */ +/*****************************************************************************/ + +#define REMOTE_WAKEUP_SUPPORT (TRUE) + +/* CDC specific configuration parameters */ +#define DATA_CLASS_SUPPORT (TRUE) +#define CIC_NOTIF_ELEM_SUPPORT (TRUE) /* Mandatory */ +#define DIC_ISOCHRONOUS_SETTING (FALSE) +#define IMPLEMENT_QUEUING (FALSE) + +/* Hardware components configuration */ +#define USB_HW_VREG_EN TRUE +#define USB_HW_PU_EN TRUE + +/* Event callbacks assignation */ +#define USB_EP0_CALLBACK USB_Control_Service + +#if DIC_ISOCHRONOUS_SETTING +#define USB_EP1_CALLBACK USB_Class_CDC_Service_Dic_Iso_In +#define USB_EP2_CALLBACK USB_Class_CDC_Service_Dic_Iso_Out +#else +#define USB_EP1_CALLBACK USB_Class_CDC_Service_Dic_Bulk_In +#define USB_EP2_CALLBACK USB_Class_CDC_Service_Dic_Bulk_Out +#endif + +#define USB_EP3_CALLBACK USB_Class_CDC_Service_Cic_Notify +#define USB_EP4_CALLBACK USB_NULL_CALLBACK +#define USB_EP5_CALLBACK USB_NULL_CALLBACK +#define USB_EP6_CALLBACK USB_NULL_CALLBACK +#define USB_EP7_CALLBACK USB_NULL_CALLBACK +#define USB_EP8_CALLBACK USB_NULL_CALLBACK +#define USB_EP9_CALLBACK USB_NULL_CALLBACK +#define USB_EP10_CALLBACK USB_NULL_CALLBACK +#define USB_EP11_CALLBACK USB_NULL_CALLBACK +#define USB_EP12_CALLBACK USB_NULL_CALLBACK +#define USB_EP13_CALLBACK USB_NULL_CALLBACK +#define USB_EP14_CALLBACK USB_NULL_CALLBACK +#define USB_EP15_CALLBACK USB_NULL_CALLBACK + +#define USB_BUS_RESET_CALLBACK USB_Reset_Service +#define USB_SUSPEND_CALLBACK USB_Suspend_Service +#define USB_SOF_CALLBACK USB_Sof_Service +#define USB_RESUME_CALLBACK USB_Resume_Service +#define USB_SLEEP_CALLBACK USB_Suspend_Service +#define USB_SPEED_DETECTION_CALLBACK USB_NULL_CALLBACK +#define USB_ERROR_CALLBACK USB_Error_Service +#define USB_STALL_CALLBACK USB_Stall_Service + +/* Endpoints configuration */ +#define USB_EP0_ENABLE TRUE +#define USB_EP0_DIR EP_CTRL +#define USB_EP0_HSHK TRUE +#define USB_EP0_SIZE 32 /* default 32 */ + +#if DIC_ISOCHRONOUS_SETTING +#define USB_EP1_ENABLE TRUE +#define USB_EP1_DIR USB_DIR_IN +#define USB_EP1_HSHK FALSE +#define USB_EP1_SIZE 32 /* default 64 */ + +#define USB_EP2_ENABLE TRUE +#define USB_EP2_DIR EP_OUT +#define USB_EP2_HSHK FALSE +#define USB_EP2_SIZE 32 /* default 64 */ +#else +#define USB_EP1_ENABLE TRUE +#define USB_EP1_DIR EP_IN +#define USB_EP1_HSHK TRUE +#define USB_EP1_SIZE 32 /* default 32 */ + +#define USB_EP2_ENABLE TRUE +#define USB_EP2_DIR EP_OUT +#define USB_EP2_HSHK TRUE +#define USB_EP2_SIZE 32 /* default 32 */ +#endif + +#define USB_EP3_ENABLE TRUE +#define USB_EP3_DIR EP_IN +#define USB_EP3_HSHK TRUE +#define USB_EP3_SIZE 32 + +#define USB_EP4_ENABLE FALSE +#define USB_EP4_DIR NA +#define USB_EP4_HSHK TRUE +#define USB_EP4_SIZE 0 + +#define USB_EP5_ENABLE FALSE +#define USB_EP5_DIR NA +#define USB_EP5_HSHK TRUE +#define USB_EP5_SIZE 0 + +#define USB_EP6_ENABLE FALSE +#define USB_EP6_DIR NA +#define USB_EP6_HSHK TRUE +#define USB_EP6_SIZE 0 + +#define USB_EP7_ENABLE FALSE +#define USB_EP7_DIR NA +#define USB_EP7_HSHK TRUE +#define USB_EP7_SIZE 0 + +#define USB_EP8_ENABLE FALSE +#define USB_EP8_DIR NA +#define USB_EP8_HSHK TRUE +#define USB_EP8_SIZE 0 + +#define USB_EP9_ENABLE FALSE +#define USB_EP9_DIR NA +#define USB_EP9_HSHK TRUE +#define USB_EP9_SIZE 0 + +#define USB_EP10_ENABLE FALSE +#define USB_EP10_DIR NA +#define USB_EP10_HSHK TRUE +#define USB_EP10_SIZE 0 + +#define USB_EP11_ENABLE FALSE +#define USB_EP11_DIR NA +#define USB_EP11_HSHK TRUE +#define USB_EP11_SIZE 0 + +#define USB_EP12_ENABLE FALSE +#define USB_EP12_DIR NA +#define USB_EP12_HSHK TRUE +#define USB_EP12_SIZE 0 + +#define USB_EP13_ENABLE FALSE +#define USB_EP13_DIR NA +#define USB_EP13_HSHK TRUE +#define USB_EP13_SIZE 0 + +#define USB_EP14_ENABLE FALSE +#define USB_EP14_DIR NA +#define USB_EP14_HSHK TRUE +#define USB_EP14_SIZE 0 + +#define USB_EP15_ENABLE FALSE +#define USB_EP15_DIR NA +#define USB_EP15_HSHK TRUE +#define USB_EP15_SIZE 0 + +/*****************************************************************************/ +/* Extern Variables Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ +/* Function Prototypes Section */ +/*****************************************************************************/ + + +/*****************************************************************************/ + +#endif /* USB_CONFIG_H_ */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.c new file mode 100644 index 0000000..adf8cd8 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.c @@ -0,0 +1,2758 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +/* MODULE UTIL1. */ + +#include "UTIL1.h" +#include /* for rand() */ + +/* Internal method prototypes */ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill); + +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief copy the string src into dst. It performs the same task as strncpy, except + - always terminates the result string. + - does not zero out the remaining part in dst. + Note: dstSize is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to copy +*/ +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + *dst = '\0'; +} + +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Concat the string src into dst. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to add + */ +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the src in the destination */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the ch in the destination */ + if (dstSize > 0) { + *dst++ = ch; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit unsigned number to convert. + */ +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val) +{ + UTIL1_Num16uToStr(dst, dstSize, (uint16_t)val); +} + +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit signed number to convert. + */ +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val) +{ + UTIL1_Num16sToStr(dst, dstSize, (int16_t)val); +} + +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit unsigned number to convert. + */ +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit signed number to convert. + */ +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int16_t)(0x8000)) { /* special case 0x8000/-32768: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-32768"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = (int16_t)(-val); + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : ShiftRightAndFill (component Utility) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill) +{ + signed char i, j; + + j = 0; + while(dst[j] != '\0') { + j++; + } + i = (signed char)nofFill; + if (i==j) { + /* nothing to do, we are done */ + } else if (i>j) { + while (j>=0) { + dst[i] = dst[j]; + i--; j--; + } + while(i>=0) { + dst[i] = fill; + i--; + } + } else { + /* hmmm, not enough space, return what we have, do nothing */ + } +} + +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit unsigned number to add + */ +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val) +{ + unsigned char buf[sizeof("256")]; /* maximum buffer size we need */ + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit signed number to add + */ +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val) +{ + unsigned char buf[sizeof("-128")]; /* maximum buffer size we need */ + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + */ +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + */ +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 8bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 8bit number to add + */ +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num) +{ + unsigned char buf[sizeof("FF")]; /* maximum buffer size we need */ + unsigned char hex; + + buf[2] = '\0'; + hex = (char)(num & 0x0F); + buf[1] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + hex = (char)((num>>4) & 0x0F); + buf[0] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 16bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 16bit number to add + */ +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num) +{ + unsigned char buf[sizeof("FFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[4] = '\0'; + i = 3; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 24bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 24bit number to add + */ +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[6] = '\0'; + i = 5; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 32bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 32bit number to add + */ +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[8] = '\0'; + i = 7; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit number to add + */ +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (unsigned long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + */ +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit signed number to convert. + */ +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int32_t)(0x80000000)) { /* special case 0x80000000/-2147483648: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-2147483648"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = -val; + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit unsigned number to convert. + */ +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ +bool UTIL1_IsLeapYear(uint16_t year) +{ + return ((((year%4)==0) && (year%100)!=0) || (year%400)==0); +} + +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day) +{ + /* see http://klausler.com/new-dayofweek.html */ + static const uint8_t skew[12] = {0,3,3,6,1,4,6,2,5,0,3,5}; + uint16_t sum; + + sum = (uint16_t)(year-1900); + sum += sum/4; + sum %= 7; + if (UTIL1_IsLeapYear(year) && (month==1 || month==2)) { + sum--; + } + sum += day; + sum %= 7; + sum += skew[month-1]; + sum %= 7; + return (uint8_t)sum; /* 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, ... */ +} + +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators) +{ + size_t lenCopied = 0, lenOverread = 0; + bool quoteMode = FALSE; /* quoteMode means the name is surrounded by ". In this mode, only a second single quote " + terminates the string. In !quoteMode a space or a '\0' may also terminate it correctly */ + bool res = ERR_OK; + #define IS_SPACE(ch) ((ch)==' '||(ch)=='\t'||(ch)=='\n'||(ch)=='\v'||(ch)=='\f'||(ch)=='\r') + + if (filename==NULL || (destname!=NULL && maxlen==0)) { + return ERR_FAILED; + } + if (filename[0] == '"') { /* translated mode */ + filename++; /* overread '"' */ + lenOverread++; + quoteMode=TRUE; + } + if (terminators == NULL) { + terminators = ""; + } + for (;;) { + if (quoteMode) { + if (filename[0] == '"') { + filename++; /* overread '"' */ + lenOverread++; + if (filename[0] != '"') { /* quoteMode is terminated by a single quote. A double quote is treated like a single quote and does not terminate it ! */ + break; /* successfully finished with this name */ + } /* else we copy the second quote " */ + } + if (filename[0] == '\0') { /* unexpected 0. stop */ + res = ERR_FAILED; + break; /* error case: no terminating double quote (") was found */ + } + } else { /* copy mode */ + if (IS_SPACE(filename[0]) || filename[0] == '\0' || strchr(terminators, filename[0]) != NULL) { /* !quoteMode is terminated by space, '\0' or by any char in terminators */ + break; + } + } + if (destname != NULL) { + if (lenCopied + 1 < maxlen) { + destname[0] = filename[0]; + destname++; + } else { + destname[0] = '\0'; /* terminate string */ + destname = NULL; /* avoid it to overwrite not allocated space */ + } + } + lenCopied++; + filename++; + } + if (destname != NULL) { + destname[0] = '\0'; + } + if (lenRead != NULL) { + *lenRead = lenCopied+lenOverread; + } + if (lenWritten != NULL) { + *lenWritten = lenCopied + 1; /* additionally a zero byte written */ + } + return res; +} + +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ +/*------------------------------------------------------------------------/ +/ Universal string handler for user console interface +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * This software is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-------------------------------------------------------------------------*/ +#ifdef __HC12__ + #pragma MESSAGE DISABLE C12056 /* message about SP debug info */ +#endif +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res) +{ +/* 123 -5 0x3ff 0b1111 0377 3.25 w " + ^ 1st call returns 123 and next ptr + ^ 2nd call returns -5 and next ptr + ^ 3rd call returns 1023 and next ptr + ^ 4th call returns 15 and next ptr + ^ 5th call returns 255 and next ptr + ^ 6th call returns 3 and next ptr, caller needs to read '.' + ^ 7th call returns 25 and next ptr + ^ 8th call fails and returns ERR_FAILED +*/ + uint32_t val; + uint8_t c, r, s = 0; + + *res = 0; + while (**str==' ') { + (*str)++; /* Skip leading spaces */ + } + c = **str; + if (c == '-') { /* negative? */ + s = 1; + c = *(++(*str)); + } + if (c == '0') { + c = *(++(*str)); + switch (c) { + case 'x': /* hexadecimal */ + r = 16; c = *(++(*str)); + break; + case 'b': /* binary */ + r = 2; c = *(++(*str)); + break; + default: + if (c <= ' ' || c == '.') { + return ERR_OK; /* single zero */ + } + if (c < '0' || c > '9') { + return ERR_FAILED; /* invalid char */ + } + r = 8; /* octal */ + break; + } /* switch */ + } else { + if (c < '0' || c > '9') { + return ERR_FAILED; /* EOL or invalid char */ + } + r = 10; /* decimal */ + } + val = 0; + while (c > ' ' && c != '.') { + if (c >= 'a') c -= 0x20; + c -= '0'; + if (c >= 17) { + c -= 7; + if (c <= 9) return ERR_FAILED; /* invalid char */ + } + if (c >= r) return ERR_FAILED; /* invalid char for current radix */ + val = val * r + c; + c = *(++(*str)); + } /* while */ + if (s) val = 0 - val; /* apply sign if needed */ + *res = (long)val; + return ERR_OK; +} +#ifdef __HC12__ + #pragma MESSAGE DEFAULT C12056 /* message about SP debug info */ +#endif + +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year) +{ + /* precondition: string points to starting of date, e.g. "01.01.10" or "12.5.2010", and date is in format dd.mm.yy or dd.mm.yyyy */ + const unsigned char *p; + + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, day)==ERR_OK + && *day > 0 && *day <= 31 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal8uNumber(&p, month)==ERR_OK + && *month > 0 && *month <= 12 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal16uNumber(&p, year)==ERR_OK + && *year > 0 && *year <= 3000 /* hopefully this is enough :-) */ + ) + { + if (*year < 100) { + *year += 2000; /* transform '10' into '2010' */ + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + *day = 0; + *month = 0; + *year = 0; + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond) +{ + /* precondition: string points to starting of time string, e.g. "03:15:05" or "03:15:05,3" or "03:15:05,17", and time is in format hh:mm:ss[,hh] */ + const unsigned char *p; + #define SCAN_IS_DIGIT(ch) ((ch)>='0'&&(ch)<='9') + + *hour = 0; + *minute = 0; + *second = 0; + *hSecond = 0; + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, hour)==ERR_OK + && *hour <= 24 + && *p==':' + ) + { + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, minute)==ERR_OK + && *minute <= 60 + ) + { + if (*p==':') { /* there is more after the minute */ + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, second)==ERR_OK + && *second <= 60 + ) + { + if (*p==',') { /* we do have either ",z" or ",hh" */ + p++; /* skip ',' */ + if (SCAN_IS_DIGIT(*p)) { + if (SCAN_IS_DIGIT(*(p+1))) { /* ,hh format */ + *hSecond = (uint8_t)((*p-'0')*10 + *(p+1)-'0'); + return ERR_OK; + } else { /* ,z format */ + *hSecond = (uint8_t)((*p-'0')*10); + p++; + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else { + return ERR_FAILED; /* illegal format, not a number, e.g. ",x" */ + } + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else if (*p==' ' || *p=='\0') { /* nothing more after the minute? Assume zero seconds */ + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _8_NOF_DIGITS (3+1) + uint8_t nofDigits = _8_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint8_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_8_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint8_t val8u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal8uNumber(&p, &val8u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int8_t)(-(int8_t)val8u); + } else { + *val = (int8_t)val8u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _16_NOF_DIGITS (5+1) + uint8_t nofDigits = _16_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint16_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_16_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint16_t val16u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal16uNumber(&p, (uint16_t*)&val16u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int16_t)(-(int16_t)val16u); + } else { + *val = (int16_t)val16u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _32_NOF_DIGITS (10+1) + uint8_t nofDigits = _32_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint32_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_32_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint32_t val32u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal32uNumber(&p, &val32u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int32_t)(-(int32_t)val32u); + } else { + *val = (int32_t)val32u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros) +{ + /* scans e.g. "-3445.071" and returns -3445 in integral part, and 71 in fractional part */ + uint8_t res; + const unsigned char *p = *str; + + *integral = 0; + *fractional = 0; + *nofFractionalZeros = 0; + res = UTIL1_ScanDecimal32sNumber(&p, integral); + if (res != ERR_OK) { + return res; + } + if (*p=='.') { + p++; /* skip '.' */ + while (*p=='0') { /* count leading zeros */ + (*nofFractionalZeros)++; + p++; /* skip leading zero */ + } + if (*p>='0' && *p<='9') { /* number */ + res = UTIL1_ScanDecimal32uNumber(&p, fractional); + if (res != ERR_OK) { + return res; + } + } + } + *str = p; /* store parsing pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strcmp(const char *, const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strcmp() function +} +*/ + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strncmp(const char *, const char *, size_t size) +{ + /Method is implemented as macro in the header file as wrapper to the standard strncmp() function +} +*/ + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ +/*** +uint16_t UTIL1_strlen(const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strlen() function +} +*/ + +static bool isHexCharacter(unsigned char ch) { + /* returns TRUE if character is a hexadecimal character */ + return (ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F'); +} + +static uint8_t PreScanHexNumber(const unsigned char **str) { + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (*p!='0') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip '0' */ + if (*p!='x') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip 'x' */ + *str = p; + return ERR_OK; +} + +static uint8_t HexToDec(const unsigned char **p, unsigned char *val) { + /* convert a hexadecimal character into a decimal value */ + unsigned char ch = **p; + + if (ch>='0' && ch<='9') { + *val = (unsigned char)(ch-'0'); + (*p)++; + return ERR_OK; + } else if (ch>='a' && ch<='f') { + *val = (unsigned char)(ch-'a'+10); + (*p)++; + return ERR_OK; + } else if (ch>='A' && ch<='F') { + *val = (unsigned char)(ch-'A'+10); + (*p)++; + return ERR_OK; + } + return ERR_FAILED; +} + +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 8; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint32_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 4; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint16_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number with 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number without 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail) +{ + int i, j; + + i = (int)UTIL1_strlen((char*)str); + j = (int)UTIL1_strlen((char*)tail); + if (j>i) { /* str is smaller than tail */ + return 1; /* cannot match */ + } + /* compare strings */ + while(str[i]==tail[j]) { + i--; + j--; + if (j<0) { + return 0; /* match */ + } + } + return 1; /* !=0 means no match */ +} + +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail) +{ + /* cut the tail from the string */ + size_t strLen, tailLen; + + if (UTIL1_strtailcmp(str, tail)!=0) { /* check if tail is present */ + return ERR_FAILED; /* tail not found */ + } + tailLen = UTIL1_strlen((char*)tail); + strLen = UTIL1_strlen((char*)str); + /* write \0 to cut the tail */ + str[strLen-tailLen] = '\0'; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num) +{ + if (num<0 && (num/100)==0) { /* e.g. -53 ==> write sign, as strcatNum32() below will not know that it is negative */ + UTIL1_chcat(dst, dstSize, '-'); + } + UTIL1_strcatNum32s(dst, dstSize, num/100); + UTIL1_chcat(dst, dstSize, '.'); + if (num<0) { + num = -num; + } + UTIL1_strcatNum16uFormatted(dst, dstSize, (uint16_t)((unsigned)num%100U), '0', 2); +} + +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr) +{ + int16_t i, len; + + len = (int16_t)UTIL1_strlen((char*)subStr); + for (i=0; *str!='\0'; i++, str++) { + if (UTIL1_strncmp((char*)str, (char*)subStr, len)==0) { + return i; /* found */ + } + } + return -1; /* not found */ +} + +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType) +{ + int i; + uint8_t res; + const unsigned char *p; + + if (nofValues<=1) { + return ERR_FAILED; /* need at least two values */ + } + p = *str; + for(i=0;i0) { + *buf++ = *p++; + bufSize--; + } + if (*p!='\"') { + return ERR_FAILED; /* no terminating double quote */ + } else { + p++; /* skip double quote */ + *buf = '\0'; /* terminate buffer */ + } + *cmd = p; /* advance pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize) +{ + uint8_t *p; + size_t nof = 0; + + if (dstSize<2) { + return; /* hmm, really to small for anything than the zero byte? */ + } + p = dst; + while(*p != '\0') { /* find end of string */ + p++; + nof++; + } + UTIL1_strcat(dst+nof, dstSize-nof, src); /* add string */ + dstSize -= nof; + while(*p != '\0' && srcPadSize>0 && dstSize>1) { + p++; + srcPadSize--; + dstSize--; + } + while(srcPadSize>0 && dstSize>1) { + *p++ = padChar; /* add padding char */ + srcPadSize--; + dstSize--; + } + *p = '\0'; /* terminate string */ +} + +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint32_t integral; + uint32_t fractional, shift; + int i; + bool isNeg; + + isNeg = (bool)(val<0); + if (isNeg) { + val = -val; /* make it positive */ + } + integral = (uint32_t)(int32_t)val; + val = val-(float)integral; /* get rid of integral part */ + shift = 1; + for(i=0;i0) { + UTIL1_chcat(dst, dstSize, '.'); + UTIL1_strcatNum32uFormatted(dst, dstSize, fractional, '0', nofFracDigits); + } +} + +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint8_t buf[32]; + + UTIL1_NumFloatToStr(buf, sizeof(buf), val, nofFracDigits); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint16_t UTIL1_GetValue16LE(uint8_t *dataP) +{ + return (uint16_t)((dataP[1]<<8)+(dataP[0])); +} + +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue24LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue32LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[3])<<24)+(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); /* MSB */ +} + +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); +} + +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); + dataP[3] = (uint8_t)((data>>24)&0xff); +} + +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max) +{ +#if 0 /* original Arduino implementation */ + return (x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min; +#else /* improved version, see https://github.com/arduino/Arduino/issues/2466 */ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +#endif +} + +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max) +{ + if (valmax) { + return max; + } + return val; +} + +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ +int32_t UTIL1_random(int32_t min, int32_t max) +{ + int32_t val; + + val = rand()%(max-min+1)+min; + return UTIL1_constrain(val, min, max); +} + +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_randomSetSeed(unsigned int seed) +{ + srand(seed); /* set random number generator seed */ +} + +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max) +{ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +} +#endif + +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes) +{ + if (nofBytes==1) { + UTIL1_strcatNum8Hex(dst, dstSize, (uint8_t)num); + } else if (nofBytes==2) { + UTIL1_strcatNum16Hex(dst, dstSize, (uint16_t)num); + } else if (nofBytes==3) { + UTIL1_strcatNum24Hex(dst, dstSize, num); + } else { /* nofBytes==4 */ + UTIL1_strcatNum32Hex(dst, dstSize, num); + } +} + +/* END UTIL1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.h new file mode 100644 index 0000000..97057e5 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1.h @@ -0,0 +1,1422 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-04-26, 14:52, # CodeGen: 4 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +#ifndef __UTIL1_H +#define __UTIL1_H + +/* MODULE UTIL1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "UTIL1config.h" /* configuration */ + +/* other includes needed */ +#include +#include /* for size_t */ +/* special version */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UTIL1_SEP_NUM_TYPE_UINT8, /* uint8_t number type */ + UTIL1_SEP_NUM_TYPE_UINT8_HEX_NO_PREFIX /* uint8_t hex number type, no 0x prefix */ +} UTIL1_SeparatedNumberType; + +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +bool UTIL1_IsLeapYear(uint16_t year); +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ + +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ + +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators); +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year); +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond); +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +#define UTIL1_strcmp(str1, str2) \ + strcmp(str1, str2) + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strncmp(str1, str2, size) \ + strncmp(str1, str2, size) + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strlen(str) \ + strlen(str) + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ + +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ + +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType); +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : ScanDoubleQuotedString (component Utility) +** +** Description : +** Scans a string inside double quotes and returns it without +** the double quotes. +** Parameters : +** NAME - DESCRIPTION +** cmd - Pointer to pointer to string to parse. +** This pointer will be advanced as much as +** parsing is done. +** * buf - Pointer to buffer where to store the string +** bufSize - Size of buffer in bytes +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros); +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize); +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Init(void); +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max); +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ + +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ + +int32_t UTIL1_random(int32_t min, int32_t max); +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ + +void UTIL1_randomSetSeed(unsigned int seed); +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ + +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max); +#endif +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ + +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes); +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ + +/* END UTIL1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __UTIL1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1config.h new file mode 100644 index 0000000..10eda65 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/UTIL1config.h @@ -0,0 +1,13 @@ +/** + * \file + * \brief Configuration header file for Utility + * + * This header file is used to configure settings of the Utility module. + */ + +#ifndef __UTIL1_CONFIG_H +#define __UTIL1_CONFIG_H + +/* no configuration supported yet */ + +#endif /* __UTIL1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/Vectors_Config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Vectors_Config.h new file mode 100644 index 0000000..29aafdd --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/Vectors_Config.h @@ -0,0 +1,206 @@ +/** ################################################################### +** Filename : Vectors_Config.h +** Processor : MK22FN512VLH12 +** Version : 1.00 +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Vectors_Config.h +** @version 01.00 +*/ +/*! +** @addtogroup Vectors_Config_module Vectors_Config module documentation +** @{ +*/ + +#ifndef __Vectors_Config_H +#define __Vectors_Config_H + +/* MODULE Vectors_Config.h */ + +#include "Cpu.h" +#include "Pins1.h" +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "MCUC1.h" +#include "UTIL1.h" +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "WAIT1.h" +#include "RTT1.h" +#include "CLS1.h" +#include "XF1.h" +#include "CS1.h" +#include "KIN1.h" +#include "PTRC1.h" +#include "AS1.h" +#include "ASerialLdd1.h" +#include "USB1.h" +#include "CDC1.h" +#include "Tx1.h" +#include "Rx1.h" +#include "TMOUT1.h" +#include "AS2.h" +#include "ASerialLdd2.h" +#include "Events.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PEX_VECTOR_TABLE 0x01U /* Vector table is managed by PEx */ + +/* Vector Address No. Pri Name Description */ +#define VECTOR_SP_MAIN &__SP_INIT /* 0x00 - ivINT_Initial_Stack_Pointer used by PE */ +#define VECTOR_1 (tIsrFunc)&__thumb_startup /* 0x01 - ivINT_Initial_Program_Counter used by PE */ +#define VECTOR_2 (tIsrFunc)&Cpu_INT_NMIInterrupt /* 0x02 -2 ivINT_NMI used by PE */ +#define VECTOR_3 (tIsrFunc)&UnhandledInterrupt /* 0x03 -1 ivINT_Hard_Fault unused by PE */ +#define VECTOR_4 (tIsrFunc)&UnhandledInterrupt /* 0x04 - ivINT_Mem_Manage_Fault unused by PE */ +#define VECTOR_5 (tIsrFunc)&UnhandledInterrupt /* 0x05 - ivINT_Bus_Fault unused by PE */ +#define VECTOR_6 (tIsrFunc)&UnhandledInterrupt /* 0x06 - ivINT_Usage_Fault unused by PE */ +#define VECTOR_7 (tIsrFunc)&UnhandledInterrupt /* 0x07 - ivINT_Reserved7 unused by PE */ +#define VECTOR_8 (tIsrFunc)&UnhandledInterrupt /* 0x08 - ivINT_Reserved8 unused by PE */ +#define VECTOR_9 (tIsrFunc)&UnhandledInterrupt /* 0x09 - ivINT_Reserved9 unused by PE */ +#define VECTOR_10 (tIsrFunc)&UnhandledInterrupt /* 0x0A - ivINT_Reserved10 unused by PE */ +#define VECTOR_11 (tIsrFunc)&vPortSVCHandler /* 0x0B - ivINT_SVCall used by PE */ +#define VECTOR_12 (tIsrFunc)&UnhandledInterrupt /* 0x0C - ivINT_DebugMonitor unused by PE */ +#define VECTOR_13 (tIsrFunc)&UnhandledInterrupt /* 0x0D - ivINT_Reserved13 unused by PE */ +#define VECTOR_14 (tIsrFunc)&vPortPendSVHandler /* 0x0E - ivINT_PendableSrvReq used by PE */ +#define VECTOR_15 (tIsrFunc)&vPortTickHandler /* 0x0F - ivINT_SysTick used by PE */ +#define VECTOR_16 (tIsrFunc)&UnhandledInterrupt /* 0x10 - ivINT_DMA0 unused by PE */ +#define VECTOR_17 (tIsrFunc)&UnhandledInterrupt /* 0x11 - ivINT_DMA1 unused by PE */ +#define VECTOR_18 (tIsrFunc)&UnhandledInterrupt /* 0x12 - ivINT_DMA2 unused by PE */ +#define VECTOR_19 (tIsrFunc)&UnhandledInterrupt /* 0x13 - ivINT_DMA3 unused by PE */ +#define VECTOR_20 (tIsrFunc)&UnhandledInterrupt /* 0x14 - ivINT_DMA4 unused by PE */ +#define VECTOR_21 (tIsrFunc)&UnhandledInterrupt /* 0x15 - ivINT_DMA5 unused by PE */ +#define VECTOR_22 (tIsrFunc)&UnhandledInterrupt /* 0x16 - ivINT_DMA6 unused by PE */ +#define VECTOR_23 (tIsrFunc)&UnhandledInterrupt /* 0x17 - ivINT_DMA7 unused by PE */ +#define VECTOR_24 (tIsrFunc)&UnhandledInterrupt /* 0x18 - ivINT_DMA8 unused by PE */ +#define VECTOR_25 (tIsrFunc)&UnhandledInterrupt /* 0x19 - ivINT_DMA9 unused by PE */ +#define VECTOR_26 (tIsrFunc)&UnhandledInterrupt /* 0x1A - ivINT_DMA10 unused by PE */ +#define VECTOR_27 (tIsrFunc)&UnhandledInterrupt /* 0x1B - ivINT_DMA11 unused by PE */ +#define VECTOR_28 (tIsrFunc)&UnhandledInterrupt /* 0x1C - ivINT_DMA12 unused by PE */ +#define VECTOR_29 (tIsrFunc)&UnhandledInterrupt /* 0x1D - ivINT_DMA13 unused by PE */ +#define VECTOR_30 (tIsrFunc)&UnhandledInterrupt /* 0x1E - ivINT_DMA14 unused by PE */ +#define VECTOR_31 (tIsrFunc)&UnhandledInterrupt /* 0x1F - ivINT_DMA15 unused by PE */ +#define VECTOR_32 (tIsrFunc)&UnhandledInterrupt /* 0x20 - ivINT_DMA_Error unused by PE */ +#define VECTOR_33 (tIsrFunc)&UnhandledInterrupt /* 0x21 - ivINT_MCM unused by PE */ +#define VECTOR_34 (tIsrFunc)&UnhandledInterrupt /* 0x22 - ivINT_FTF unused by PE */ +#define VECTOR_35 (tIsrFunc)&UnhandledInterrupt /* 0x23 - ivINT_Read_Collision unused by PE */ +#define VECTOR_36 (tIsrFunc)&UnhandledInterrupt /* 0x24 - ivINT_LVD_LVW unused by PE */ +#define VECTOR_37 (tIsrFunc)&UnhandledInterrupt /* 0x25 - ivINT_LLWU unused by PE */ +#define VECTOR_38 (tIsrFunc)&UnhandledInterrupt /* 0x26 - ivINT_WDOG_EWM unused by PE */ +#define VECTOR_39 (tIsrFunc)&UnhandledInterrupt /* 0x27 - ivINT_RNG unused by PE */ +#define VECTOR_40 (tIsrFunc)&UnhandledInterrupt /* 0x28 - ivINT_I2C0 unused by PE */ +#define VECTOR_41 (tIsrFunc)&UnhandledInterrupt /* 0x29 - ivINT_I2C1 unused by PE */ +#define VECTOR_42 (tIsrFunc)&UnhandledInterrupt /* 0x2A - ivINT_SPI0 unused by PE */ +#define VECTOR_43 (tIsrFunc)&UnhandledInterrupt /* 0x2B - ivINT_SPI1 unused by PE */ +#define VECTOR_44 (tIsrFunc)&UnhandledInterrupt /* 0x2C - ivINT_I2S0_Tx unused by PE */ +#define VECTOR_45 (tIsrFunc)&UnhandledInterrupt /* 0x2D - ivINT_I2S0_Rx unused by PE */ +#define VECTOR_46 (tIsrFunc)&ASerialLdd1_Interrupt /* 0x2E 112 ivINT_LPUART0 used by PE */ +#define VECTOR_47 (tIsrFunc)&ASerialLdd2_Interrupt /* 0x2F 112 ivINT_UART0_RX_TX used by PE */ +#define VECTOR_48 (tIsrFunc)&ASerialLdd2_Interrupt /* 0x30 112 ivINT_UART0_ERR used by PE */ +#define VECTOR_49 (tIsrFunc)&UnhandledInterrupt /* 0x31 - ivINT_UART1_RX_TX unused by PE */ +#define VECTOR_50 (tIsrFunc)&UnhandledInterrupt /* 0x32 - ivINT_UART1_ERR unused by PE */ +#define VECTOR_51 (tIsrFunc)&UnhandledInterrupt /* 0x33 - ivINT_UART2_RX_TX unused by PE */ +#define VECTOR_52 (tIsrFunc)&UnhandledInterrupt /* 0x34 - ivINT_UART2_ERR unused by PE */ +#define VECTOR_53 (tIsrFunc)&UnhandledInterrupt /* 0x35 - ivINT_Reserved53 unused by PE */ +#define VECTOR_54 (tIsrFunc)&UnhandledInterrupt /* 0x36 - ivINT_Reserved54 unused by PE */ +#define VECTOR_55 (tIsrFunc)&UnhandledInterrupt /* 0x37 - ivINT_ADC0 unused by PE */ +#define VECTOR_56 (tIsrFunc)&UnhandledInterrupt /* 0x38 - ivINT_CMP0 unused by PE */ +#define VECTOR_57 (tIsrFunc)&UnhandledInterrupt /* 0x39 - ivINT_CMP1 unused by PE */ +#define VECTOR_58 (tIsrFunc)&RTOSCNTRLDD1_Interrupt /* 0x3A 112 ivINT_FTM0 used by PE */ +#define VECTOR_59 (tIsrFunc)&UnhandledInterrupt /* 0x3B - ivINT_FTM1 unused by PE */ +#define VECTOR_60 (tIsrFunc)&UnhandledInterrupt /* 0x3C - ivINT_FTM2 unused by PE */ +#define VECTOR_61 (tIsrFunc)&UnhandledInterrupt /* 0x3D - ivINT_Reserved61 unused by PE */ +#define VECTOR_62 (tIsrFunc)&UnhandledInterrupt /* 0x3E - ivINT_RTC unused by PE */ +#define VECTOR_63 (tIsrFunc)&UnhandledInterrupt /* 0x3F - ivINT_RTC_Seconds unused by PE */ +#define VECTOR_64 (tIsrFunc)&UnhandledInterrupt /* 0x40 - ivINT_PIT0 unused by PE */ +#define VECTOR_65 (tIsrFunc)&UnhandledInterrupt /* 0x41 - ivINT_PIT1 unused by PE */ +#define VECTOR_66 (tIsrFunc)&UnhandledInterrupt /* 0x42 - ivINT_PIT2 unused by PE */ +#define VECTOR_67 (tIsrFunc)&UnhandledInterrupt /* 0x43 - ivINT_PIT3 unused by PE */ +#define VECTOR_68 (tIsrFunc)&UnhandledInterrupt /* 0x44 - ivINT_PDB0 unused by PE */ +#define VECTOR_69 (tIsrFunc)&USB_ISR /* 0x45 0 ivINT_USB0 used by PE */ +#define VECTOR_70 (tIsrFunc)&UnhandledInterrupt /* 0x46 - ivINT_Reserved70 unused by PE */ +#define VECTOR_71 (tIsrFunc)&UnhandledInterrupt /* 0x47 - ivINT_Reserved71 unused by PE */ +#define VECTOR_72 (tIsrFunc)&UnhandledInterrupt /* 0x48 - ivINT_DAC0 unused by PE */ +#define VECTOR_73 (tIsrFunc)&UnhandledInterrupt /* 0x49 - ivINT_MCG unused by PE */ +#define VECTOR_74 (tIsrFunc)&UnhandledInterrupt /* 0x4A - ivINT_LPTMR0 unused by PE */ +#define VECTOR_75 (tIsrFunc)&UnhandledInterrupt /* 0x4B - ivINT_PORTA unused by PE */ +#define VECTOR_76 (tIsrFunc)&UnhandledInterrupt /* 0x4C - ivINT_PORTB unused by PE */ +#define VECTOR_77 (tIsrFunc)&UnhandledInterrupt /* 0x4D - ivINT_PORTC unused by PE */ +#define VECTOR_78 (tIsrFunc)&UnhandledInterrupt /* 0x4E - ivINT_PORTD unused by PE */ +#define VECTOR_79 (tIsrFunc)&UnhandledInterrupt /* 0x4F - ivINT_PORTE unused by PE */ +#define VECTOR_80 (tIsrFunc)&UnhandledInterrupt /* 0x50 - ivINT_SWI unused by PE */ +#define VECTOR_81 (tIsrFunc)&UnhandledInterrupt /* 0x51 - ivINT_Reserved81 unused by PE */ +#define VECTOR_82 (tIsrFunc)&UnhandledInterrupt /* 0x52 - ivINT_Reserved82 unused by PE */ +#define VECTOR_83 (tIsrFunc)&UnhandledInterrupt /* 0x53 - ivINT_Reserved83 unused by PE */ +#define VECTOR_84 (tIsrFunc)&UnhandledInterrupt /* 0x54 - ivINT_Reserved84 unused by PE */ +#define VECTOR_85 (tIsrFunc)&UnhandledInterrupt /* 0x55 - ivINT_Reserved85 unused by PE */ +#define VECTOR_86 (tIsrFunc)&UnhandledInterrupt /* 0x56 - ivINT_Reserved86 unused by PE */ +#define VECTOR_87 (tIsrFunc)&UnhandledInterrupt /* 0x57 - ivINT_FTM3 unused by PE */ +#define VECTOR_88 (tIsrFunc)&UnhandledInterrupt /* 0x58 - ivINT_DAC1 unused by PE */ +#define VECTOR_89 (tIsrFunc)&UnhandledInterrupt /* 0x59 - ivINT_ADC1 unused by PE */ +#define VECTOR_90 (tIsrFunc)&UnhandledInterrupt /* 0x5A - ivINT_Reserved90 unused by PE */ +#define VECTOR_91 (tIsrFunc)&UnhandledInterrupt /* 0x5B - ivINT_Reserved91 unused by PE */ +#define VECTOR_92 (tIsrFunc)&UnhandledInterrupt /* 0x5C - ivINT_Reserved92 unused by PE */ +#define VECTOR_93 (tIsrFunc)&UnhandledInterrupt /* 0x5D - ivINT_Reserved93 unused by PE */ +#define VECTOR_94 (tIsrFunc)&UnhandledInterrupt /* 0x5E - ivINT_Reserved94 unused by PE */ +#define VECTOR_95 (tIsrFunc)&UnhandledInterrupt /* 0x5F - ivINT_Reserved95 unused by PE */ +#define VECTOR_96 (tIsrFunc)&UnhandledInterrupt /* 0x60 - ivINT_Reserved96 unused by PE */ +#define VECTOR_97 (tIsrFunc)&UnhandledInterrupt /* 0x61 - ivINT_Reserved97 unused by PE */ +#define VECTOR_98 (tIsrFunc)&UnhandledInterrupt /* 0x62 - ivINT_Reserved98 unused by PE */ +#define VECTOR_99 (tIsrFunc)&UnhandledInterrupt /* 0x63 - ivINT_Reserved99 unused by PE */ +#define VECTOR_100 (tIsrFunc)&UnhandledInterrupt /* 0x64 - ivINT_Reserved100 unused by PE */ +#define VECTOR_101 (tIsrFunc)&UnhandledInterrupt /* 0x65 - ivINT_Reserved101 unused by PE */ + +#ifdef __cplusplus +} +#endif + +/* END Vectors_Config.h */ + +#endif /* __Vectors_Config_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file is a part of Processor Expert static initialization +** library for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.c new file mode 100644 index 0000000..4d4d672 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.c @@ -0,0 +1,351 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Enabled +** RTOS : FRTOS1 +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +/* MODULE WAIT1. */ + +#include "WAIT1.h" + + +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ +#if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif +#else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif +#endif +#endif +void WAIT1_Wait10Cycles(void) +{ + /* This function will wait 10 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* NOTE: Cortex-M0 and M4 have 1 cycle for a NOP */ + /* Compiler is GNUC */ + __asm ( + /* bl Wait10Cycles() to here: [4] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [4] for overhead */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ + #if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif + #else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif + #endif +#endif +void WAIT1_Wait100Cycles(void) +{ + /* This function will spend 100 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + __asm ( + /* bl to here: [4] */ + "push {r0} \n\t" /* [2] */ + "movs r0, #0 \n\t" /* [1] */ + "loop: \n\t" + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "add r0,#1 \n\t" /* [1] */ + "cmp r0,#9 \n\t" /* [1] */ + "bls loop \n\t" /* [3] taken, [1] not taken */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "pop {r0} \n\t" /* [2] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [10] for overhead */ + " li a5,20 \n\t" + "Loop: \n\t" + " addi a5,a5,-1 \n\t" + " bgtz a5, Loop \n\t" + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitCycles(uint16_t cycles) +{ + /*lint -save -e522 function lacks side effect. */ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter() 100) { + WAIT1_Wait100Cycles(); + counter -= 100; + } + while(counter > 10) { + WAIT1_Wait10Cycles(); + counter -= 10; + } +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitLongCycles(uint32_t cycles) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter()60000) { + WAIT1_WaitCycles(60000); + cycles -= 60000; + } + WAIT1_WaitCycles((uint16_t)cycles); + /*lint -restore */ +#endif +} + +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Waitms(uint16_t ms) +{ + /*lint -save -e522 function lacks side effect. */ + uint32_t msCycles; /* cycles for 1 ms */ + + /* static clock/speed configuration */ + msCycles = WAIT1_NofCyclesMs(1, WAIT1_INSTR_CLOCK_HZ); + while(ms>0) { + WAIT1_WaitLongCycles(msCycles); + ms--; + } + /*lint -restore */ +} +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void WAIT1_WaitOSms(void) +{ + Method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Init(void) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + /* init cycle counter */ + KIN1_InitCycleCounter(); + KIN1_ResetCycleCounter(); + KIN1_EnableCycleCounter(); +#endif +} + +/* END WAIT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.h new file mode 100644 index 0000000..c8d07f0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1.h @@ -0,0 +1,259 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:30, # CodeGen: 7 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Enabled +** RTOS : FRTOS1 +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +#ifndef __WAIT1_H +#define __WAIT1_H + +/* MODULE WAIT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "WAIT1config.h" /* configuration */ + +/* other includes needed */ +#if WAIT1_CONFIG_USE_RTOS_WAIT + /* include RTOS header files */ + #include "FRTOS1.h" + #include "FreeRTOS.h" /* for vTaskDelay() */ + #include "task.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define WAIT1_INSTR_CLOCK_HZ CPU_CORE_CLK_HZ /* for Kinetis, use core clock as base for instruction execution */ +#else + extern uint32_t SystemCoreClock; /* clock frequency variable defined system_.h of the SDK */ + #define WAIT1_INSTR_CLOCK_HZ SystemCoreClock /* core clock frequency in Hz */ +#endif +#define WAIT1_NofCyclesMs(ms, hz) ((ms)*((hz)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesUs(us, hz) ((us)*(((hz)/1000)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesNs(ns, hz) (((ns)*(((hz)/1000)/1000))/1000) /* calculates the needed cycles based on bus clock frequency */ + +#define WAIT1_WAIT_C(cycles) \ + ( (cycles)<=10 ? \ + WAIT1_Wait10Cycles() \ + : WAIT1_WaitCycles((uint16_t)cycles) \ + ) /*!< wait for some cycles */ + + +void WAIT1_Wait10Cycles(void); +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Wait100Cycles(void); +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitCycles(uint16_t cycles); +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Waitms(uint16_t ms); +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitus(us) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesUs((us),WAIT1_INSTR_CLOCK_HZ)==0)||(us)==0) ? \ + (void)0 : \ + ( ((us)/1000)==0 ? (void)0 : WAIT1_Waitms((uint16_t)((us)/1000))) \ + , (WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)==0) ? (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitns(ns) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesNs((ns), WAIT1_INSTR_CLOCK_HZ)==0)||(ns)==0) ? \ + (void)0 : \ + WAIT1_Waitus((ns)/1000) \ + , (WAIT1_NofCyclesNs((ns)%1000, WAIT1_INSTR_CLOCK_HZ)==0) ? \ + (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesNs(((ns)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ + +#if WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_WaitOSms(ms) vTaskDelay(pdMS_TO_TICKS(ms)) /* use FreeRTOS API */ +#else + #define WAIT1_WaitOSms(ms) WAIT1_Waitms(ms) /* use normal wait */ +#endif +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitLongCycles(uint32_t cycles); +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Init(void); +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END WAIT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __WAIT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1config.h new file mode 100644 index 0000000..f3b881c --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/WAIT1config.h @@ -0,0 +1,27 @@ +/** + * \file + * \brief Configuration header file for Wait + * + * This header file is used to configure settings of the busy waiting module. + */ + +#ifndef __WAIT1_CONFIG_H +#define __WAIT1_CONFIG_H + +#include "MCUC1.h" /* include library configuration */ + +#ifndef WAIT1_CONFIG_USE_CYCLE_COUNTER + #define WAIT1_CONFIG_USE_CYCLE_COUNTER (1 && (MCUC1_CONFIG_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3)) + /*!< 1: Use hardware cycle counter (if present, only on Cortex-M3 or higher), 0: not using hardware cycle counter */ +#endif + +#ifndef WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_CONFIG_USE_RTOS_WAIT (1 && MCUC1_CONFIG_SDK_USE_FREERTOS) + /*!< 1: Use RTOS wait if RTOS is present; 0: use normal busy waiting */ +#endif + +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + #include "KIN1.h" /* include Cortex utility functions */ +#endif + +#endif /* __WAIT1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.c new file mode 100644 index 0000000..a3bce9b --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.c @@ -0,0 +1,1213 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:34, # CodeGen: 8 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +/* MODULE XF1. */ +/** + * @file xformatc.c + * + * @brief Printf C implementation. + * + * Tested wuth the following operating systems / compilers : + * + * - Visual studio 6 + * - Visual studio 2008 / Windows CE + * - MinGw 32 + * - Linux i686 + * - Linux x86_64 + * - GCC wiith embedded ARM. + * - Linux armel + * - HCS08 with Freescale compiler. + * - SDCC (Z80 and 8051) + * + * @author Mario Viara + * + * + * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) + * This is a free software and is opened for education, research and commercial + * developments under license policy of following terms: + * + * - This is a free software and there is NO WARRANTY. + * - No restriction on use. You can use, modify and redistribute it for personal, + * non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * - Redistributions of source code must retain the above copyright notice. + * + * To contact the author send an email to mario_at_viara.eu + * + */ +#include "XF1.h" + +/** + * Default largest int is long + */ +#ifndef LONG +#define LONG long +#endif + +/** + * Define the double type if not defined + */ +#ifndef DOUBLE +#define DOUBLE double +#endif + + +/** + * Default long long type + */ +#ifndef LONGLONG +#define LONGLONG long long +#endif + + +/** + * Definition to convert integer part of floating point + * number if supported we use the long long type + */ +#if XCFG_FORMAT_LONGLONG +#define FLOAT_LONG LONGLONG +#define FLOAT_VALUE llvalue +#define FLOAT_TYPE FLAG_TYPE_LONGLONG +#else +#define FLOAT_LONG LONG +#define FLOAT_VALUE lvalue +#define FLOAT_TYPE FLAG_TYPE_LONG +#endif + +/** + * Structure with all parameter used + */ +struct param_s +{ + /** + * Buffer for current integer value and for temporary + * double value defined as union to save stack. + */ + union + { + unsigned LONG lvalue; +#if XCFG_FORMAT_LONGLONG + unsigned LONGLONG llvalue; +#endif +#if XCFG_FORMAT_FLOAT + DOUBLE dvalue; +#endif + } values; + + /** + * Pointer to the output buffer + */ + char* out; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point argument + */ + DOUBLE dbl; + + /** + * Integer part of floating point + */ + unsigned FLOAT_LONG iPart; + +#endif + + + /** + * Current length of the output buffer + */ + int length; + + /** + * Field precision + */ + int prec; + + /** + * Field width + */ + int width; + + + /** + * Count the number of char emitted + */ + unsigned count; + + + /** + * Parser flags + */ + unsigned flags; + +#define FLAG_TYPE_INT 0x0000 /* Argument is integer */ +#define FLAG_TYPE_LONG 0x0001 /* Argument is long */ +#define FLAG_TYPE_SIZEOF 0x0002 /* Argument is size_t */ +#define FLAG_TYPE_LONGLONG 0x0003 /* Argument is long long */ +#define FLAG_TYPE_MASK 0x0003 /* Mask for field type */ +#define FLAG_PREC 0x0004 /* Precision set */ +#define FLAG_LEFT 0x0008 /* Left alignment */ +#define FLAG_BLANK 0x0010 /* Blank before positive integer number */ +#define FLAG_PREFIX 0x0020 /* Prefix required */ +#define FLAG_PLUS 0x0040 /* Force a + before positive number */ +#define FLAG_UPPER 0x0080 /* Output in upper case letter */ +#define FLAG_DECIMAL 0x0100 /* Decimal field */ +#define FLAG_INTEGER 0x0200 /* Integer field */ +#define FLAG_MINUS 0x0400 /* Field is negative */ +#define FLAG_VALUE 0x0800 /* Value set */ +#define FLAG_BUFFER 0x1000 /* Buffer set */ + + /** + * Length of the prefix + */ + int prefixlen; + + /* Buffer to store the field prefix */ + char prefix[2]; + + + /** Buffer to store the biggest integer number in binary */ +#if XCFG_FORMAT_LONGLONG + char buffer[sizeof(LONGLONG)*8+1]; +#else + char buffer[sizeof(LONG)*8+1]; +#endif + + /* Radix for ASCII integer conversion */ + unsigned char radix; + + /* char used for padding */ + char pad; + + + /** + * Current state + */ + char state; + +}; + + +/** + * Enum for the internal state machine + */ +enum State +{ + /* Normal state outputting literal */ + ST_NORMAL = 0, + /* Just read % */ + ST_PERCENT = 1, + + /* Just read flag */ + ST_FLAG = 2, + + /* Just read the width */ + ST_WIDTH = 3, + + /* Just read '.' */ + ST_DOT= 4, + + /* Just read the precision */ + ST_PRECIS = 5, + + /* Just read the size */ + ST_SIZE = 6, + + /* Just read the type specifier */ + ST_TYPE = 7 +}; + +/** + * Enum for char class + */ +enum CharClass +{ + /* Other char */ + CH_OTHER = 0, + /* The % char */ + CH_PERCENT = 1, + /* The . char */ + CH_DOT = 2, + /* The * char */ + CH_STAR = 3, + /* The 0 char */ + CH_ZERO = 4, + /* Digit 0-9 */ + CH_DIGIT = 5, + /* Flag chars */ + CH_FLAG = 6, + /* Size chars */ + CH_SIZE = 7, + /* Type chars */ + CH_TYPE = 8 +}; + + + +/** + * String used when %s is a null parameter + */ +static const char ms_null[] = "(null)"; +/* + * String for true value + */ +static const char ms_true[] = "True"; + +/** + * String for false value + */ +static const char ms_false[]= "False"; + + +/* + * Digit values + */ +static const char ms_digits[] = "0123456789abcdef"; + + +/* + * This table contains the next state for all char and it will be + * generate using xformattable.c + */ + +static const unsigned char formatStates[] = +{ + 0x06,0x00,0x00,0x06,0x00,0x01,0x00,0x00, + 0x10,0x00,0x03,0x06,0x00,0x06,0x02,0x10, + 0x04,0x45,0x45,0x45,0x45,0x05,0x05,0x05, + 0x05,0x35,0x30,0x00,0x50,0x60,0x00,0x00, + 0x00,0x20,0x28,0x38,0x50,0x50,0x00,0x00, + 0x00,0x30,0x30,0x30,0x50,0x50,0x00,0x00, + 0x08,0x20,0x20,0x28,0x20,0x20,0x20,0x00, + 0x08,0x60,0x60,0x60,0x60,0x60,0x60,0x00, + 0x00,0x70,0x78,0x78,0x78,0x70,0x78,0x00, + 0x07,0x08,0x00,0x00,0x07,0x00,0x00,0x08, + 0x08,0x00,0x00,0x08,0x00,0x08,0x00,0x00, + 0x08,0x00,0x07 +}; + + + + +/** + * Convert an unsigned value in one string + * + * All parameter are in the passed structure + * + * @param prec - Minimum precision + * @param lvalue - Unsigned value + * @param radix - Radix (Supported values 2/8/10/16) + * + * @param out - Buffer with the converted value. + */ +static void ulong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.lvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.lvalue & 0x01; + param->values.lvalue >>= 1; + break; + + case 8: + digit = param->values.lvalue & 0x07; + param->values.lvalue >>= 3; + break; + + case 16: + digit = param->values.lvalue & 0x0F; + param->values.lvalue >>= 4; + break; + + default: + case 10: + digit = param->values.lvalue % 10; + param->values.lvalue /= 10; + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} + + +#if XCFG_FORMAT_LONGLONG +#ifdef XCFG_FORMAT_LONG_ARE_LONGLONG +#define ullong2a ulong2a +#else +static void ullong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.llvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.llvalue & 0x01; + param->values.llvalue >>= 1; + break; + + case 8: + digit = param->values.llvalue & 0x07; + param->values.llvalue >>= 3; + break; + + case 16: + digit = param->values.llvalue & 0x0F; + param->values.llvalue >>= 4; + break; + + default: + case 10: + digit = param->values.llvalue % 10; + param->values.llvalue /= 10; + + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} +#endif +#endif + +#if 1 /* << EST */ +typedef struct { + char *s; + size_t space; +} StrOutBuffer; + +static void putCharIntoBufMaxLen(void *arg, char c) { + StrOutBuffer *buff = (StrOutBuffer*)arg; + if (buff->space > 0) { + buff->space--; + *(buff->s)++ = c; + } +} + +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args) { + int res = -1; + StrOutBuffer out; + + out.space = max_len; + out.s = buf; + if (max_len <= 1) { + *buf = 0; + return 0; + } else { + out.space--; /* teminal zero*/ + } + res = (int)XF1_xvformat(putCharIntoBufMaxLen, (void *)&out, fmt, args); + *(out.s) = 0; + if (res > 0) { + res = out.s - buf; + } + return res; +} +#endif + +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ +/** + * Printf like using variable arguments. + * + * @param outchar - Pointer to the function to output one new char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param ... - Arguments + * + * @return The number of char emitted. + * + * @see xvformat + */ +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) +{ + va_list list; + unsigned count; + + va_start(list,fmt); + count = XF1_xvformat(outchar,arg,fmt,list); + + va_end(list); + + return count; +} + +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +/** + * We do not want use any library function. + * + * @param s - C string + * @return The length of the string + */ +static unsigned xstrlen(const char *s) +{ + const char *i; + + for (i = s ; *i ; i++) + { + } + + return (unsigned)(i - s); +} + +static unsigned outBuffer(void (*myoutchar)(void *arg,char),void *arg,const char *buffer,int len,unsigned toupper) +{ + unsigned count = 0; + int i; + char c; + + for (i = 0; i < len ; i++) + { + c = buffer[i]; + + if (toupper && (c >= 'a' && c <= 'z')) + { + c -= 'a' - 'A'; + } + + (*myoutchar)(arg,c); + count++; + } + + return count; +} + + +static unsigned outChars(void (*myoutchar)(void *arg,char),void *arg,char ch,int len) +{ + unsigned count= 0; + + while (len-- > 0) + { + (*myoutchar)(arg,ch); + count++; + } + + return count; +} + +#if 1 /* << EST added xsprintf() */ +static void putCharIntoBuf(void *arg, char c) { + char **s = (char **)arg; + *(*s)++ = c; +} + +int xsprintf(char *buf, const char *fmt, va_list args) { + int res; + + res = (int)XF1_xvformat(putCharIntoBuf, (void *)&buf, fmt, args); + *buf = 0; + return res; +} +#endif + +/* + * Lint want declare list as const but list is an obscured pointer so + * the warning is disabled. + */ +/*lint -save -e818 */ + + +/** + * Printf like format function. + * + * General format : + * + * %[width][.precision][flags]type + * + * - width Is the minimum size of the field. + * + * - precision Is the maximum size of the field. + * + * Supported flags : + * + * - l With integer number the argument will be of type long. + * - ll With integer number the argument will be of type long long. + * - Space for positive integer a space will be added before. + * - z Compatible with C99 the argument is size_t (aka sizeof(void *)) + * - + A + sign prefix positive number. + * - # A prefix will be printed (o for octal,0x for hex,0b for binary) + * - 0 Value will be padded with zero (default is spacwe) + * - - Left justify as default filed have rigth justification. + * + * Supported type : + * + * - s Null terminated string of char. + * - S Null terminated string of char in upper case. + * - i Integer number. + * - d Integer number. + * - u Unsigned number. + * - x Unsigned number in hex. + * - X Unsigned number in hex upper case. + * - b Binary number + * - o Octal number + * - p Pointer will be emitted with the prefix -> + * - P Pointer in upper case letter. + * - f Floating point number. + * - B Boolean value printed as True / False. + * + * @param outchar - Pointer to the function to output one char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param args - List parameters. + * + * @return The number of char emitted. + */ +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list _args) +{ + XCFG_FORMAT_STATIC struct param_s param; + int i; + char c; + +#if XCFG_FORMAT_VA_COPY + va_list args; + + va_copy(args,_args); +#else +#define args _args +#endif + + param.count = 0; + param.state = ST_NORMAL; + + while (*fmt) + { + c = *fmt++; + + if (c < ' ' || c > 'z') + i = (int)CH_OTHER; + else + i = formatStates[c - ' '] & 0x0F; + + param.state = formatStates[(i << 3) + param.state] >> 4; + + + switch (param.state) + { + default: + case ST_NORMAL: + (*outchar)(arg,c); + param.count++; + break; + + case ST_PERCENT: + param.flags = param.length = param.prefixlen = param.width = param.prec = 0; + param.pad = ' '; + break; + + case ST_WIDTH: + if (c == '*') + param.width = (int)va_arg(args,int); + else + param.width = param.width * 10 + (c - '0'); + break; + + case ST_DOT: + break; + + case ST_PRECIS: + param.flags |= FLAG_PREC; + if (c == '*') + param.prec = (int)va_arg(args,int); + else + param.prec = param.prec * 10 + (c - '0'); + break; + + case ST_SIZE: + switch (c) + { + default: + break; + case 'z': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_SIZEOF; + break; + + case 'l': +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONG) + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONGLONG; + } + else + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; + + } +#else + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; +#endif + break; + + + } + break; + + case ST_FLAG: + switch (c) + { + default: + break; + case '-': + param.flags |= FLAG_LEFT; + break; + case '0': + param.pad = '0'; + break; + case ' ': + param.flags |= FLAG_BLANK; + break; + case '#': + param.flags |= FLAG_PREFIX; + break; + case '+': + param.flags |= FLAG_PLUS; + break; + } + break; + + case ST_TYPE: + switch (c) + { + default: + param.length = 0; + break; + + /* + * Pointer upper case + */ + case 'P': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Pointer + */ + case 'p': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_INTEGER | FLAG_TYPE_SIZEOF; + param.radix = 16; + param.prec = sizeof(void *) * 2; + param.prefix[0] = '-'; + param.prefix[1] = '>'; + param.prefixlen = 2; + break; + + /* + * Binary number + */ + case 'b': + param.flags |= FLAG_INTEGER; + param.radix = 2; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'b'; + param.prefixlen = 2; + } + break; + + /* + * Octal number + */ + case 'o': + param.flags |= FLAG_INTEGER; + param.radix = 8; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefixlen = 1; + } + break; + + /* + * Hex number upper case letter. + */ + case 'X': + /* no break */ + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Hex number lower case + */ + case 'x': + param.flags |= FLAG_INTEGER; + param.radix = 16; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'x'; + param.prefixlen = 2; + } + break; + + /* + * Integer number radix 10 + */ + case 'd': + case 'i': + param.flags |= FLAG_DECIMAL|FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Unsigned number + */ + case 'u': + param.flags |= FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Upper case string + */ + case 'S': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Normal string + */ + case 's': + param.out = va_arg(args,char *); + if (param.out == 0) + param.out = (char *)ms_null; + param.length = (int)xstrlen(param.out); + break; + + /* + * Upper case char + */ + case 'C': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Char + */ + case 'c': + param.out = param.buffer; + param.buffer[0] = (char)va_arg(args,int); + param.length = 1; + break; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point number + */ + case 'f': + if (!(param.flags & FLAG_PREC)) + { + param.prec = 6; + } + + param.dbl = va_arg(args,DOUBLE); + param.values.dvalue = 0.50; + for (i = 0 ; i < param.prec ; i++) + param.values.dvalue /= 10.0; + + if (param.dbl < 0) + { + param.flags |= FLAG_MINUS; + param.dbl -= param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= (FLOAT_LONG)param.iPart; + param.dbl = - param.dbl; + } + else + { + param.dbl += param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= param.iPart; + } + + + for (i = 0 ;i < param.prec ;i++) + param.dbl *= 10.0; + + param.values.lvalue = (unsigned LONG)param.dbl; + + param.out = param.buffer + sizeof(param.buffer) - 1; + param.radix = 10; + if (param.prec) + { + ulong2a(¶m); + *param.out -- = '.'; + param.length ++; + } + param.flags |= FLAG_INTEGER | FLAG_BUFFER | + FLAG_DECIMAL | FLAG_VALUE | FLOAT_TYPE; + + param.prec = 0; + param.values.FLOAT_VALUE = (unsigned FLOAT_LONG)param.iPart; + break; +#endif + + /** + * Boolean value + */ + case 'B': + if (va_arg(args,int) != 0) + param.out = (char*)ms_true; + else + param.out = (char*)ms_false; + + param.length = (int)xstrlen(param.out); + break; + + + } + + /* + * Process integer number + */ + if (param.flags & FLAG_INTEGER) + { + if (param.prec == 0) + param.prec = 1; + + if (!(param.flags & FLAG_VALUE)) + { + switch (param.flags & FLAG_TYPE_MASK) + { + case FLAG_TYPE_SIZEOF: + param.values.lvalue = (unsigned LONG)va_arg(args,void *); + break; + case FLAG_TYPE_LONG: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,long); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned long); + break; + + case FLAG_TYPE_INT: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,int); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned int); + break; +#if XCFG_FORMAT_LONGLONG + case FLAG_TYPE_LONGLONG: + param.values.llvalue = (LONGLONG)va_arg(args,long long); + break; +#endif + } + + } + + if ((param.flags & FLAG_PREFIX) && param.values.lvalue == 0) + { + param.prefixlen = 0; + } + + + /* + * Manage signed integer + */ + if (param.flags & FLAG_DECIMAL) + { +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + { + if ((LONGLONG)param.values.llvalue < 0) + { + param.values.llvalue = ~param.values.llvalue + 1; + param.flags |= FLAG_MINUS; + } + } + else + { +#endif + if ((LONG)param.values.lvalue < 0) + { + param.values.lvalue = ~param.values.lvalue + 1; + param.flags |= FLAG_MINUS; + + } +#if XCFG_FORMAT_LONGLONG + } +#endif + if (!(param.flags & FLAG_MINUS) && (param.flags & FLAG_BLANK)) + { + param.prefix[0] = ' '; + param.prefixlen = 1; + } + } + + if ((param.flags & FLAG_BUFFER) == 0) + { + param.out = param.buffer + sizeof(param.buffer) - 1; + } + + +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + ullong2a(¶m); + else + ulong2a(¶m); +#else + + ulong2a(¶m); +#endif + param.out++; + + /* + * Check if a sign is required + */ + if (param.flags & (FLAG_MINUS|FLAG_PLUS)) + { + c = param.flags & FLAG_MINUS ? '-' : '+'; + + if (param.pad == '0') + { + param.prefixlen = 1; + param.prefix[0] = c; + } + else + { + *--param.out = c; + param.length++; + } + } + + + } + else + { + if (param.width && param.length > param.width) + { + param.length = param.width; + } + + } + + /* + * Now width contain the size of the pad + */ + param.width -= (param.length + param.prefixlen); + + param.count += outBuffer(outchar,arg,param.prefix,param.prefixlen,param.flags & FLAG_UPPER); + if (!(param.flags & FLAG_LEFT)) + param.count += outChars(outchar,arg,param.pad,param.width); + param.count += outBuffer(outchar,arg,param.out,param.length,param.flags & FLAG_UPPER); + if (param.flags & FLAG_LEFT) + param.count += outChars(outchar,arg,param.pad,param.width); + + } + } + +#if XCFG_FORMAT_VA_COPY + va_end(args); +#endif + + return param.count; +} +/*lint -restore */ + +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsprintf(char *buf, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsprintf(buf, fmt, args); + va_end(args); + return res; +} + + +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsnprintf(buf, max_len, fmt, args); + va_end(args); + return res; +} + +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Deinit(void) +{ + /* nothing needed */ +} + +/* END XF1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.h new file mode 100644 index 0000000..98f43c1 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1.h @@ -0,0 +1,191 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyK22_OpenPnP_Master +** Processor : MK22FN512VLH12 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2018-08-27, 14:02, # CodeGen: 0 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +#ifndef __XF1_H +#define __XF1_H + +/* MODULE XF1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "XF1config.h" /* configuration */ + +/* other includes needed */ +#include /* open argument list support */ +#include /* for size_t */ + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ + /* inform the GNU compiler about printf() style functions, so the compiler can check the arguments */ + #define XF1_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#else + #define XF1_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +/* low level functions */ +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args); +int xsprintf(char *buf, const char *fmt, va_list args); + +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ + +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list args); +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +int XF1_xsprintf(char *buf, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(2,3); +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +void XF1_Init(void); +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void XF1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END XF1. */ + +#endif +/* ifndef __XF1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1config.h new file mode 100644 index 0000000..cb73d79 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/XF1config.h @@ -0,0 +1,75 @@ +#ifndef __XF1_CONFIG_H +#define __XF1_CONFIG_H + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_FLOAT 0 /* 1: enable, 0: disable floating format (component property) */ +#endif + + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_STATIC /* static */ /* used for the buffer. WARNING: using 'static' makes it non-reentrant! */ +#endif + +/** + * MSVC use in x64 model IL32P64 architecture so the largest integer + * is not a standard C integer. + */ +#if defined(_MSC_VER) && defined(_M_AMD64) +#define LONG long long +#define XCFG_FORMAT_LONG_ARE_LONGLONG +#endif + + +/** + * SDCC support only float and for now do not support long long + */ +#ifdef __SDCC +#define DOUBLE float +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 0 +#endif +#endif + + +/** + * Define internal parameters as volatile for 8 bit cpu define + * XCFG_FORMAT_STATIC=static to reduce stack usage. + */ +#ifndef XCFG_FORMAT_STATIC + #define XCFG_FORMAT_STATIC +#endif + +/** + * Define XCFG_FORMAT_FLOAT=0 to remove floating point support + */ +#ifndef XCFG_FORMAT_FLOAT +#define XCFG_FORMAT_FLOAT 1 +#endif + +/** + * Detect support for va_copy this macro must be called for example + * in x86_64 machine to adjust the stack frame when an argument of va_list + * is passed over functions. + */ +#ifndef XCFG_FORMAT_VA_COPY +#if defined(__GNUC__) && defined(__x86_64__) +#define XCFG_FORMAT_VA_COPY 1 +#endif + + +#ifndef XCFG_FORMAT_VA_COPY +#define XCFG_FORMAT_VA_COPY 0 +#endif + +#endif + + +/** + * Define to 0 to support long long type (prefix ll) + */ +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 1 +#endif + + +#endif /* __XF1_CONFIG_H */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.c new file mode 100644 index 0000000..4676b0d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.c @@ -0,0 +1,354 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +CRCB_t * pxCurrentCoRoutine = NULL; +static UBaseType_t uxTopCoRoutineReadyPriority = 0; +static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) +{ +BaseType_t xReturn; +CRCB_t *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) +{ +TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +CRCB_t *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pxContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) +{ +CRCB_t *pxUnblockedCRCB; +BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + +#endif /* configUSE_CO_ROUTINES == 0 */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.h new file mode 100644 index 0000000..a98ccad --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/croutine.h @@ -0,0 +1,721 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/deprecated_definitions.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/deprecated_definitions.h new file mode 100644 index 0000000..d869789 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/deprecated_definitions.h @@ -0,0 +1,280 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/derivative.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/derivative.h new file mode 100644 index 0000000..d900748 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/derivative.h @@ -0,0 +1,10 @@ +#ifndef __DERIVATIVE_USB +#define __DERIVATIVE_USB + +/* Include the derivative-specific header file */ +#include "Cpu.h" + +#define __MK_xxx_H__ + +#endif + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.c new file mode 100644 index 0000000..692288f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.c @@ -0,0 +1,754 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ + +/* The following bit fields convey control information in a task's event list +item value. It is important they don't clash with the +taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if configUSE_16_BIT_TICKS == 1 + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#else + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#endif + +typedef struct EventGroupDef_t +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) + { + EventGroup_t *pxEventBits; + + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticEventGroup_t equals the size of the real + event group structure. */ + volatile size_t xSize = sizeof( StaticEventGroup_t ); + configASSERT( xSize == sizeof( EventGroup_t ) ); + } /*lint !e529 xSize is referenced if configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + /* The user has provided a statically allocated event group - use it. */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + this event group was created statically in case the event group + is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + /* xEventGroupCreateStatic should only ever be called with + pxEventGroupBuffer pointing to a pre-allocated (compile time + allocated) StaticEventGroup_t variable. */ + traceEVENT_GROUP_CREATE_FAILED(); + } + + return pxEventBits; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) + { + EventGroup_t *pxEventBits; + + /* Allocate the event group. Justification for MISRA deviation as + follows: pvPortMalloc() always ensures returned memory blocks are + aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the EventGroup_t structure - which (if you + follow it through) is the alignment requirements of the TickType_t type + (EventBits_t being of TickType_t itself). Therefore, whenever the + stack alignment requirements are greater than or equal to the + TickType_t alignment requirements the cast is safe. In other cases, + where the natural word size of the architecture is less than + sizeof( TickType_t ), the TickType_t variables will be accessed in two + or more reads operations, and the alignment requirements is only that + of each individual read. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note this + event group was allocated statically in case the event group is + later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ + } + + return pxEventBits; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t uxOriginalBitValue, uxReturn; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + the task unblocks, but some compilers mistakenly generate a + warning about uxReturn being returned without being set if the + assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + xTimeoutOccurred = pdTRUE; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + bits it was waiting for were set, it is possible that since it + unblocked another task has set the bits. If this is the case + then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn, uxControlBits = 0; +BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task is going to block to wait for its required bits to be + set. uxControlBits are used to remember the specified behaviour of + this call to xEventGroupWaitBits() - for use when the event bits + unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + some compilers mistakenly generate a warning about the variable + being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + xTimeoutOccurred = pdTRUE; + } + taskEXIT_CRITICAL(); + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ +UBaseType_t uxSavedInterruptStatus; +EventGroup_t const * const pxEventBits = xEventGroup; +EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +ListItem_t *pxListItem, *pxNext; +ListItem_t const *pxListEnd; +List_t const * pxList; +EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + item before removing the task from the event list. The + eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + that is was unblocked due to its required bits matching, rather + than because it timed out. */ + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + used here as the list item may have been removed from the event list + and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +EventGroup_t *pxEventBits = xEventGroup; +const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + it again. */ + vPortFree( pxEventBits ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + ( void ) xTaskResumeAll(); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from +an interrupt. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from +an interrupt. */ +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) +{ +BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if (configUSE_TRACE_FACILITY == 1) + + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) + { + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.h new file mode 100644 index 0000000..dc627ea --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/event_groups.h @@ -0,0 +1,758 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
+	// StaticEventGroup_t is a publicly accessible structure that has the same
+	// size and alignment requirements as the real event group structure.  It is
+	// provided as a mechanism for applications to know the size of the event
+	// group (which is dependent on the architecture and configuration file
+	// settings) without breaking the strict data hiding policy by exposing the
+	// real event group internals.  This StaticEventGroup_t variable is passed
+	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
+	// the event group's data structures
+	StaticEventGroup_t xEventGroupBuffer;
+
+	// Create the event group without dynamically allocating any memory.
+	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+   
+ */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; + void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/freertos_tasks_c_additions.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/freertos_tasks_c_additions.h new file mode 100644 index 0000000..8b09ef2 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/freertos_tasks_c_additions.h @@ -0,0 +1,138 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* freertos_tasks_c_additions.h Rev. 1.4 */ +#ifndef FREERTOS_TASKS_C_ADDITIONS_H +#define FREERTOS_TASKS_C_ADDITIONS_H + +#include +#if !defined(__HIWARE__) /* << EST */ + #include +#endif + +#if (configUSE_TRACE_FACILITY == 0) +#error "configUSE_TRACE_FACILITY must be enabled" +#endif + +#define FREERTOS_DEBUG_CONFIG_MAJOR_VERSION 1 +#define FREERTOS_DEBUG_CONFIG_MINOR_VERSION 2 + +/* NOTE!! + * Default to a FreeRTOS version which didn't include these macros. FreeRTOS + * v7.5.3 is used here. + */ +#ifndef tskKERNEL_VERSION_BUILD +#define tskKERNEL_VERSION_BUILD 3 +#endif +#ifndef tskKERNEL_VERSION_MINOR +#define tskKERNEL_VERSION_MINOR 5 +#endif +#ifndef tskKERNEL_VERSION_MAJOR +#define tskKERNEL_VERSION_MAJOR 7 +#endif + +/* NOTE!! + * The configFRTOS_MEMORY_SCHEME macro describes the heap scheme using a value + * 1 - 5 which corresponds to the following schemes: + * + * heap_1 - the very simplest, does not permit memory to be freed + * heap_2 - permits memory to be freed, but not does coalescence adjacent free + * blocks. + * heap_3 - simply wraps the standard malloc() and free() for thread safety + * heap_4 - coalesces adjacent free blocks to avoid fragmentation. Includes + * absolute address placement option + * heap_5 - as per heap_4, with the ability to span the heap across + * multiple nonOadjacent memory areas + * heap_6 - reentrant newlib implementation + */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 3 /* thread safe malloc */ +#endif + +#if ((configUSE_HEAP_SCHEME > 6) || (configUSE_HEAP_SCHEME < 1)) /* <= 10) && (tskKERNEL_VERSION_MINOR >= 2) +// Need the portARCH_NAME define +#ifndef portARCH_NAME +#define portARCH_NAME NULL +#endif +#if defined(__GNUC__) +char *const portArch_Name __attribute__((section(".rodata"))) = portARCH_NAME; +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +char *const portArch_Name __attribute__((used)) = portARCH_NAME; +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma required=portArch_Name +char *const portArch_Name = portARCH_NAME; +#endif +#else +char *const portArch_Name = NULL; +#endif // tskKERNEL_VERSION_MAJOR + +#if defined(__GNUC__) + const uint8_t FreeRTOSDebugConfig[] __attribute__((section(".rodata"))) = +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) + const uint8_t FreeRTOSDebugConfig[] __attribute__((used)) = +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma required=FreeRTOSDebugConfig + const uint8_t FreeRTOSDebugConfig[] = +#else /* << EST generic compiler */ + const uint8_t FreeRTOSDebugConfig[] = +#endif +{ + FREERTOS_DEBUG_CONFIG_MAJOR_VERSION, + FREERTOS_DEBUG_CONFIG_MINOR_VERSION, + tskKERNEL_VERSION_MAJOR, + tskKERNEL_VERSION_MINOR, + tskKERNEL_VERSION_BUILD, + configUSE_HEAP_SCHEME, + offsetof(struct tskTaskControlBlock, pxTopOfStack), +#if (tskKERNEL_VERSION_MAJOR > 8) + offsetof(struct tskTaskControlBlock, xStateListItem), +#else + offsetof(struct tskTaskControlBlock, xGenericListItem), +#endif + offsetof(struct tskTaskControlBlock, xEventListItem), + offsetof(struct tskTaskControlBlock, pxStack), + offsetof(struct tskTaskControlBlock, pcTaskName), + offsetof(struct tskTaskControlBlock, uxTCBNumber), + offsetof(struct tskTaskControlBlock, uxTaskNumber), + configMAX_TASK_NAME_LEN, + configMAX_PRIORITIES, +#if (tskKERNEL_VERSION_MAJOR >= 10) && (tskKERNEL_VERSION_MINOR >= 2) + configENABLE_MPU, + configENABLE_FPU, + configENABLE_TRUSTZONE, + configRUN_FREERTOS_SECURE_ONLY, + 0, // 32-bit align + 0, 0, 0, 0 // padding +#else + 0 // pad to 32-bit boundary +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif // FREERTOS_TASKS_C_ADDITIONS_H + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_1.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_1.c new file mode 100644 index 0000000..f540c1d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_1.c @@ -0,0 +1,168 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==1 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * The simplest possible implementation of pvPortMalloc(). Note that this + * implementation does NOT allow allocated memory to be freed again. + * + * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Index into the ucHeap array. */ +static size_t xNextFreeByte = ( size_t ) 0; + +/*-----------------------------------------------------------*/ +static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; +//static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if( portBYTE_ALIGNMENT != 1 ) + { + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + #endif + + vTaskSuspendAll(); + { + if( pucAlignedHeap == NULL ) + { + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + } + + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = pucAlignedHeap + xNextFreeByte; + xNextFreeByte += xWantedSize; + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and + heap_4.c for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; + + /* Force an assert as it is invalid to call this function. */ + configASSERT( pv == NULL ); +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); +} + +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xNextFreeByte = 0; + pucAlignedHeap = NULL; +} +#endif + +#endif /* configUSE_HEAP_SCHEME==1 */ /* << EST */ + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_2.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_2.c new file mode 100644 index 0000000..97febb0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_2.c @@ -0,0 +1,296 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==2 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block (and so will fragment memory). See heap_4.c for + * an equivalent that does combine adjacent blocks into single larger blocks. + * + * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* + * Initialises the heap structures before their first use. + */ +static void prvHeapInit( void ); + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + + +static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +BlockLink_t *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ +static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +//static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the BlockLink_t structure + at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This unexpected casting is to keep some compilers from issuing + byte alignment warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; + + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* xEnd is used to mark the end of the list of free blocks. */ + xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; + xEnd.pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xEnd.pxNextFreeBlock = NULL; + xEnd.xBlockSize = 0; + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + xHeapHasBeenInitialised = pdFALSE; +} +#endif +#endif /* configUSE_HEAP_SCHEME==2 */ /* << EST */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_3.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_3.c new file mode 100644 index 0000000..5d6a383 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_3.c @@ -0,0 +1,109 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==3 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.0 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Implementation of pvPortMalloc() and vPortFree() that relies on the + * compilers own malloc() and free() implementations. + * + * This file can only be used if the linker is configured to to generate + * a heap memory area. + * + * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn; + + vTaskSuspendAll(); + { + pvReturn = malloc( xWantedSize ); + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + if( pv ) + { + vTaskSuspendAll(); + { + free( pv ); + traceFREE( pv, 0 ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* configUSE_HEAP_SCHEME==3 */ /* << EST */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_4.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_4.c new file mode 100644 index 0000000..3596d8f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_4.c @@ -0,0 +1,467 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==4 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static unsigned char ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static unsigned char __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#elif( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +#if 0 +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#else /* << EST do not optimize this variable, needed for NXP TAD plugin */ +static const volatile size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#endif + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; +size_t uxAddress; +size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( portBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + pxEnd = NULL; /* force initialization of heap next time a block gets allocated */ + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xFreeBytesRemaining = 0; + xMinimumEverFreeBytesRemaining = 0; + xBlockAllocatedBit = 0; +} +#endif +#endif /* configUSE_HEAP_SCHEME==4 */ /* << EST */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_5.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_5.c new file mode 100644 index 0000000..475f185 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_5.c @@ -0,0 +1,499 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==5 && configSUPPORT_DYNAMIC_ALLOCATION==1) +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() that allows the heap to be defined + * across multiple non-contigous blocks and combines (coalescences) adjacent + * memory blocks as they are freed. + * + * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative + * implementations, and the memory management pages of http://www.FreeRTOS.org + * for more information. + * + * Usage notes: + * + * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). + * pvPortMalloc() will be called if any task objects (tasks, queues, event + * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be + * called before any other objects are defined. + * + * vPortDefineHeapRegions() takes a single parameter. The parameter is an array + * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as + * + * typedef struct HeapRegion + * { + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * } HeapRegion_t; + * + * The array is terminated using a NULL zero sized region definition, and the + * memory regions defined in the array ***must*** appear in address order from + * low address to high address. So the following is a valid example of how + * to use the function. + * + * HeapRegion_t xHeapRegions[] = + * { + * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 + * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 + * { NULL, 0 } << Terminates the array. + * }; + * + * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). + * + * Note 0x80000000 is the lower address so appears in the array first. + * + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); + + vTaskSuspendAll(); + { + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) +{ +BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; +size_t xAlignedHeap; +size_t xTotalRegionSize, xTotalHeapSize = 0; +BaseType_t xDefinedRegions = 0; +size_t xAddress; +const HeapRegion_t *pxHeapRegion; + + /* Can only call once! */ + configASSERT( pxEnd == NULL ); + + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + + while( pxHeapRegion->xSizeInBytes > 0 ) + { + xTotalRegionSize = pxHeapRegion->xSizeInBytes; + + /* Ensure the heap region starts on a correctly aligned boundary. */ + xAddress = ( size_t ) pxHeapRegion->pucStartAddress; + if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + xAddress += ( portBYTE_ALIGNMENT - 1 ); + xAddress &= ~portBYTE_ALIGNMENT_MASK; + + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; + } + + xAlignedHeap = xAddress; + + /* Set xStart if it has not already been set. */ + if( xDefinedRegions == 0 ) + { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + } + else + { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); + + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( xAddress > ( size_t ) pxEnd ); + } + + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; + + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + xAddress = xAlignedHeap + xTotalRegionSize; + xAddress -= xHeapStructSize; + xAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = ( BlockLink_t * ) xAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; + pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if( pxPreviousFreeBlock != NULL ) + { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } + + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + + /* Move onto the next HeapRegion_t structure. */ + xDefinedRegions++; + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + } + + xMinimumEverFreeBytesRemaining = xTotalHeapSize; + xFreeBytesRemaining = xTotalHeapSize; + + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +/*-----------------------------------------------------------*/ + +#endif /* configUSE_HEAP_SCHEME==5 */ /* << EST */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.c new file mode 100644 index 0000000..c161cf5 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.c @@ -0,0 +1,200 @@ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) +/** + * \file heap_useNewlib.c + * \brief Wrappers required to use newlib malloc-family within FreeRTOS. + * + * \par Overview + * Route FreeRTOS memory management functions to newlib's malloc family. + * Thus newlib and FreeRTOS share memory-management routines and memory pool, + * and all newlib's internal memory-management requirements are supported. + * + * \author Dave Nadler + * \date 1-July-2017 + * + * \see https://sourceware.org/newlib/libc.html#Reentrancy + * \see https://sourceware.org/newlib/libc.html#malloc + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fenv_005flock + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fmalloc_005flock + * \see https://sourceforge.net/p/freertos/feature-requests/72/ + * \see http://www.billgatliff.com/newlib.html + * \see http://wiki.osdev.org/Porting_Newlib + * \see http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html + * + * + * \copyright + * (c) Dave Nadler 2017, All Rights Reserved. + * Web: http://www.nadler.com + * email: drn@nadler.com + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Use or redistributions of source code must retain the above copyright notice, + * this list of conditions, ALL ORIGINAL COMMENTS, and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include // maps to newlib... +#include // mallinfo... +#include // ENOMEM + +#include "freeRTOS.h" // defines public interface we're implementing here +#if !defined(configUSE_NEWLIB_REENTRANT) || (configUSE_NEWLIB_REENTRANT!=1) + #warning "#define configUSE_NEWLIB_REENTRANT 1 // Required for thread-safety of newlib sprintf, strtok, etc..." + // If you're *really* sure you don't need FreeRTOS's newlib reentrancy support, remove this warning... +#endif +#include "task.h" + +// ================================================================================================ +// External routines required by newlib's malloc (sbrk/_sbrk, __malloc_lock/unlock) +// ================================================================================================ + +#if 0 // suggested minimal implementation from https://sourceware.org/newlib/libc.html#Syscalls: + // sbrk: Increase program data space. As malloc and related functions depend on this, + // it is useful to have a working implementation. The following suffices for a standalone system; + // it exploits the symbol _end automatically defined by the GNU linker. + caddr_t sbrk(int incr) { + extern char _end; /* Defined by the linker */ + static char *heap_end; + char *prev_heap_end; + if (heap_end == 0) { + heap_end = &_end; + } + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) { + write (1, "Heap and stack collision\n", 25); + abort (); + } + heap_end += incr; + return (caddr_t) prev_heap_end; + } +#endif +#if 0 // Freescale implementation + caddr_t _sbrk(int incr) + { + extern char end __asm("end"); + extern char heap_limit __asm("__HeapLimit"); + static char *heap_end; + char *prev_heap_end; + if (heap_end == NULL) + heap_end = &end; + prev_heap_end = heap_end; + if (heap_end + incr > &heap_limit) + { + errno = ENOMEM; + return (caddr_t)-1; + } + heap_end += incr; + return (caddr_t)prev_heap_end; + } +#endif + +#ifndef NDEBUG + static int totalBytesProvidedBySBRK = 0; +#endif +extern char configLINKER_HEAP_BASE_SYMBOL, configLINKER_HEAP_LIMIT_SYMBOL, configLINKER_HEAP_SIZE_SYMBOL; // make sure to define these symbols in linker command file +static int heapBytesRemaining = (int)&configLINKER_HEAP_SIZE_SYMBOL; // that's (&__HeapLimit)-(&__HeapBase) + +//! sbrk/_sbrk version supporting reentrant newlib (depends upon above symbols defined by linker control file). +char * sbrk(int incr) { + static char *currentHeapEnd = &configLINKER_HEAP_BASE_SYMBOL; + vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started + char *previousHeapEnd = currentHeapEnd; + if (currentHeapEnd + incr > &configLINKER_HEAP_LIMIT_SYMBOL) { + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + #elif 0 + // If you want to alert debugger or halt... + while(1) { __asm("bkpt #0"); }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop forever) + #else + // If you prefer to believe your application will gracefully trap out-of-memory... + _impure_ptr->_errno = ENOMEM; // newlib's thread-specific errno + xTaskResumeAll(); + #endif + return (char *)-1; // the malloc-family routine that called sbrk will return 0 + } + currentHeapEnd += incr; + heapBytesRemaining -= incr; + #ifndef NDEBUG + totalBytesProvidedBySBRK += incr; + #endif + xTaskResumeAll(); + return (char *) previousHeapEnd; +} +//! Synonym for sbrk. +char * _sbrk(int incr) { return sbrk(incr); }; + +void __malloc_lock(struct _reent *p) { vTaskSuspendAll(); }; +void __malloc_unlock(struct _reent *p) { (void)xTaskResumeAll(); }; + +// newlib also requires implementing locks for the application's environment memory space, +// accessed by newlib's setenv() and getenv() functions. +// As these are trivial functions, momentarily suspend task switching (rather than semaphore). +// ToDo: Move __env_lock/unlock to a separate newlib helper file. +void __env_lock() { vTaskSuspendAll(); }; +void __env_unlock() { (void)xTaskResumeAll(); }; + +/// /brief Wrap malloc/malloc_r to help debug who requests memory and why. +/// Add to the linker command line: -Xlinker --wrap=malloc -Xlinker --wrap=_malloc_r +// Note: These functions are normally unused and stripped by linker. +void *__wrap_malloc(size_t nbytes) { + extern void * __real_malloc(size_t nbytes); + void *p = __real_malloc(nbytes); // Solely for debug breakpoint... + return p; +}; +void *__wrap__malloc_r(void *reent, size_t nbytes) { + extern void * __real__malloc_r(size_t nbytes); + void *p = __real__malloc_r(nbytes); // Solely for debug breakpoint... + return p; +}; + + +// ================================================================================================ +// Implement FreeRTOS's memory API using newlib-provided malloc family. +// ================================================================================================ + +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION { + void *p = malloc(xSize); + return p; +} +void vPortFree( void *pv ) PRIVILEGED_FUNCTION { + free(pv); +}; + +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION { + struct mallinfo mi = mallinfo(); + return mi.fordblks + heapBytesRemaining; +} + +// GetMinimumEverFree is not available in newlib's malloc implementation. +// So, no implementation provided: size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +//! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; + +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.txt b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.txt new file mode 100644 index 0000000..e0ddeb9 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/heap_useNewlib.txt @@ -0,0 +1,7 @@ +heap_useNewlib.txt +------------------ + +For details, see +- http://www.nadler.com/embedded/newlibAndFreeRTOS.html +- http://mcuoneclipse.com/2017/07/02/using-freertos-with-newlib-and-newlib-nano + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/hidef.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/hidef.h new file mode 100644 index 0000000..aa99b54 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/hidef.h @@ -0,0 +1,60 @@ +/******************************************************/ +/** +* @file hidef.h +* Machine/compiler dependent declarations. +*/ +/*---------------------------------------------------- + Copyright (c) Freescale DevTech + All rights reserved + Do not modify! + *****************************************************/ + +#ifndef _H_HIDEF_ +#define _H_HIDEF_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(__CWCC__) + #pragma gcc_extensions on + + /**** Version for ColFire V1 */ + #include + #include "types.h" + + /*!< Macro to enable all interrupts. */ + #define EnableInterrupts __asm ("CPSIE i") + + /*!< Macro to disable all interrupts. */ + #define DisableInterrupts __asm ("CPSID i") + +#elif defined(__IAR_SYSTEMS_ICC__) + #include + + #define EnableInterrupts __enable_interrupt(); + #define DisableInterrupts __disable_interrupt(); + +#elif defined (__CC_ARM) + #define EnableInterrupts __enable_irq(); + #define DisableInterrupts __disable_irq(); + +#elif defined (__GNUC__) + #include + #include "types.h" + + /*!< Macro to enable all interrupts. */ + #define EnableInterrupts __asm ("CPSIE i") + + /*!< Macro to disable all interrupts. */ + #define DisableInterrupts __asm ("CPSID i") +#endif + +#ifdef __cplusplus + } +#endif + +#endif + +/*****************************************************/ +/* end hidef.h */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.c new file mode 100644 index 0000000..d304411 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.c @@ -0,0 +1,199 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; + + /* Write known values into the list if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); + listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pxContainer = NULL; + + /* Write known values into the list item if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t * const pxIndex = pxList->pxIndex; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t *pxIterator; +const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert the new list item into the list, sorted in xItemValue order. + + If the list already contains a list item with the same item value then the + new list item should be placed after it. This ensures that TCBs which are + stored in ready lists (all of which have the same xItemValue value) get a + share of the CPU. However, if the xItemValue is the same as the back marker + the iteration loop below will not end. Therefore the value is checked + first, and the algorithm slightly modified if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are + listed below. In addition see https://www.freertos.org/FAQHelp.html for + more tips, and ensure configASSERT() is defined! + https://www.freertos.org/a00110.html#configASSERT + + 1) Stack overflow - + see https://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M + parts where numerically high priority values denote low actual + interrupt priorities, which can seem counter intuitive. See + https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition + of configMAX_SYSCALL_INTERRUPT_PRIORITY on + https://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ + { + /* There is nothing to do here, just iterating to the wanted + insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list +item. */ +List_t * const pxList = pxItemToRemove->pxContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pxContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.h new file mode 100644 index 0000000..355ff81 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/list.h @@ -0,0 +1,413 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H + #error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + + /* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + + /* Define macros that will assert if one of the structure members does not + contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/message_buffer.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/message_buffer.h new file mode 100644 index 0000000..784fc31 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/message_buffer.h @@ -0,0 +1,800 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. + */ +typedef void * MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
+
+ * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+const size_t xMessageBufferSizeBytes = 100;
+
+    // Create a message buffer that can hold 100 bytes.  The memory used to hold
+    // both the message buffer structure and the messages themselves is allocated
+    // dynamically.  Each message added to the buffer consumes an additional 4
+    // bytes which are used to hold the lengh of the message.
+    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
+
+    if( xMessageBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // message buffer.
+    }
+    else
+    {
+        // The message buffer was created successfully and can now be used.
+    }
+
+
+ * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
+                                                  uint8_t *pucMessageBufferStorageArea,
+                                                  StaticMessageBuffer_t *pxStaticMessageBuffer );
+
+ * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the messages.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the messages within the message
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the message buffer structure.
+StaticMessageBuffer_t xMessageBufferStruct;
+
+void MyFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+
+    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
+                                                 ucBufferStorage,
+                                                 &xMessageBufferStruct );
+
+    // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
+    // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
+    // reference the created message buffer in other message buffer API calls.
+
+    // Other code that uses the message buffer can go here.
+}
+
+
+ * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
+                           const void *pvTxData,
+                           size_t xDataLengthBytes,
+                           TickType_t xTicksToWait );
+
+ *
+ * Sends a discrete message to the message buffer.  The message can be any
+ * length that fits within the buffer's free space, and is copied into the
+ * buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param xTicksToWait The maximum amount of time the calling task should remain
+ * in the Blocked state to wait for enough space to become available in the
+ * message buffer, should the message buffer have insufficient space when
+ * xMessageBufferSend() is called.  The calling task will never block if
+ * xTicksToWait is zero.  The block time is specified in tick periods, so the
+ * absolute time it represents is dependent on the tick frequency.  The macro
+ * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
+ * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
+ * the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The number of bytes written to the message buffer.  If the call to
+ * xMessageBufferSend() times out before there was enough space to write the
+ * message into the message buffer then zero is returned.  If the call did not
+ * time out then xDataLengthBytes is returned.
+ *
+ * Example use:
+
+void vAFunction( MessageBufferHandle_t xMessageBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the message buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the message buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xMessageBufferSend() times out before there was enough
+        // space in the buffer for the data to be written.
+    }
+
+    // Send the string to the message buffer.  Return immediately if there is
+    // not enough space in the buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+}
+
+ * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
+                                  const void *pvTxData,
+                                  size_t xDataLengthBytes,
+                                  BaseType_t *pxHigherPriorityTaskWoken );
+
+ *
+ * Interrupt safe version of the API function that sends a discrete message to
+ * the message buffer.  The message can be any length that fits within the
+ * buffer's free space, and is copied into the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xMessageBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xMessageBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes actually written to the message buffer.  If the
+ * message buffer didn't have enough free space for the message to be stored
+ * then 0 is returned, otherwise xDataLengthBytes is returned.
+ *
+ * Example use:
+
+// A message buffer that has already been created.
+MessageBufferHandle_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the message buffer.
+    xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
+                                            ( void * ) pcStringToSend,
+                                            strlen( pcStringToSend ),
+                                            &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
+                              void *pvRxData,
+                              size_t xBufferLengthBytes,
+                              TickType_t xTicksToWait );
+
+ * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: +
+void vAFunction( MessageBuffer_t xMessageBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive the next message from the message buffer.  Wait in the Blocked
+    // state (so not using any CPU processing time) for a maximum of 100ms for
+    // a message to become available.
+    xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
+                                            ( void * ) ucRxData,
+                                            sizeof( ucRxData ),
+                                            xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+}
+
+ * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) + + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
+                                     void *pvRxData,
+                                     size_t xBufferLengthBytes,
+                                     BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: +
+// A message buffer that has already been created.
+MessageBuffer_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next message from the message buffer.
+    xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) + + +/** + * message_buffer.h +
+size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
+
+ * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) +#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ + +/** + * message_buffer.h +
+ size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
+ 
+ * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_prototypes.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_prototypes.h new file mode 100644 index 0000000..900111e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_prototypes.h @@ -0,0 +1,158 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API functions. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of timers.h API functions. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of event_group.h API functions. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; + + + +#endif /* MPU_PROTOTYPES_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.c new file mode 100644 index 0000000..f59350b --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.c @@ -0,0 +1,1342 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if configENABLE_MPU /* << EST: only compile this module if MPU is actually enabled and supported */ + +/** + * @brief Calls the port specific code to raise the privilege. + * + * @return pdFALSE if privilege was raised, pdTRUE otherwise. + */ +BaseType_t xPortRaisePrivilege( void ) FREERTOS_SYSTEM_CALL; + +/** + * @brief If xRunningPrivileged is not pdTRUE, calls the port specific + * code to reset the privilege, otherwise does nothing. + */ +void vPortResetPrivilege( BaseType_t xRunningPrivileged ); +/*-----------------------------------------------------------*/ + +BaseType_t xPortRaisePrivilege( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged; + + /* Check whether the processor is already privileged. */ + xRunningPrivileged = portIS_PRIVILEGED(); + + /* If the processor is not already privileged, raise privilege. */ + if( xRunningPrivileged != pdTRUE ) + { + portRAISE_PRIVILEGE(); + } + + return xRunningPrivileged; +} +/*-----------------------------------------------------------*/ + +void vPortResetPrivilege( BaseType_t xRunningPrivileged ) +{ + if( xRunningPrivileged != pdTRUE ) + { + portRESET_PRIVILEGE(); + } +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestricted( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestrictedStatic( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskAbortDelay( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + eTaskState eReturn; + + eReturn = eTaskGetState( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspendAll(); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskResumeAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskResumeAll(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ +{ +TickType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ +{ +UBaseType_t uxReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ +{ +char *pcReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTaskGetName( xTaskToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetHandle( pcNameToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskList( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleRunTimeCounter(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHookFunction_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + vPortResetPrivilege( xRunningPrivileged ); + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + configSTACK_DEPTH_TYPE uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetTimeOutState( pxTimeOut ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGenericNotify( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + uint32_t ulReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + ulReturn = ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return ulReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyStateClear( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueSpacesAvailable( xQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + void * xReturn; + + xReturn = xQueueGetMutexHolder( xSemaphore ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutex( ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetMemberHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueUnregisterQueue( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + const char *MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + const char *pcReturn; + + pcReturn = pcQueueGetName( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueDelete( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void *MPU_pvPortMalloc( size_t xSize ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortFree( void *pv ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortFree( pv ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortInitialiseBlocks( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortInitialiseBlocks(); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + size_t MPU_xPortGetFreeHeapSize( void ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxTimerBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void *MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + void * pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTimerGetTimerID( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetTimerID( xTimer, pvNewID ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerIsTimerActive( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetTimerDaemonTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerPendFunctionCall( xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetReloadMode( xTimer, uxAutoReload ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + const char * pcReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTimerGetName( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetPeriod( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetExpiryTime( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreate(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vEventGroupDelete( xEventGroup ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vStreamBufferDelete( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsFull( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReset( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + +/* Functions that the application writer wants to execute in privileged mode +can be defined in application_defined_privileged_functions.h. The functions +must take the same format as those above whereby the privilege state on exit +equals the privilege state on entry. For example: + +void MPU_FunctionName( [parameters ] ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + FunctionName( [parameters ] ); + + vPortResetPrivilege( xRunningPrivileged ); +} +*/ + +#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" +#endif + +#endif /* configENABLE_MPU */ /* << EST: only compile this module if MPU is actually enabled and supported */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.h new file mode 100644 index 0000000..b65f6b0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/mpu_wrappers.h @@ -0,0 +1,187 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + /* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + + /* Map standard tasks.h API functions to the MPU equivalents. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelay MPU_vTaskDelay + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define xTaskGetHandle MPU_xTaskGetHandle + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskNotifyWait MPU_xTaskNotifyWait + #define ulTaskNotifyTake MPU_ulTaskNotifyTake + #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + /* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueGenericReset MPU_xQueueGenericReset + + #if( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif + + /* Map standard timer.h API functions to the MPU equivalents. */ + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall + #define pcTimerGetName MPU_pcTimerGetName + #define vTimerSetReloadMode MPU_vTimerSetReloadMode + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #define xTimerGenericCommand MPU_xTimerGenericCommand + + /* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + #define vEventGroupDelete MPU_vEventGroupDelete + + /* Map standard message/stream_buffer.h API functions to the MPU + equivalents. */ + #define xStreamBufferSend MPU_xStreamBufferSend + #define xStreamBufferReceive MPU_xStreamBufferReceive + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferIsFull MPU_xStreamBufferIsFull + #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty + #define xStreamBufferReset MPU_xStreamBufferReset + #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable + #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable + #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + + + /* Remove the privileged function macro, but keep the PRIVILEGED_DATA + macro so applications can place data in privileged access sections + (useful when using statically allocated objects). */ + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define FREERTOS_SYSTEM_CALL + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/port.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/port.c new file mode 100644 index 0000000..dc5e9f6 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/port.c @@ -0,0 +1,1704 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * FreeRTOS for 56800EX port by Richy Ye in Jan. 2013. + *----------------------------------------------------------*/ +/* Scheduler includes. */ +#include "FreeRTOS.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portmacro.h" /* for configCPU_FAMILY */ +#include "task.h" +#include "portTicks.h" /* for CPU_CORE_CLK_HZ used in configSYSTICK_CLOCK_HZ */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if MCUC1_CONFIG_NXP_SDK_2_0_USED + #include "fsl_lptmr.h" /* SDK low power timer interface */ + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "LPTMR_PDD.h" /* PDD interface to low power timer */ + #include "SIM_PDD.h" /* PDD interface to system integration module */ + #endif +#endif + +#include "MCUC1.h" /* include SDK and API used */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +#if( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* --------------------------------------------------- */ +/* Let the user override the pre-loading of the initial LR with the address of + prvTaskExitError() in case is messes up unwinding of the stack in the + debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif +/* --------------------------------------------------- */ +/* macros dealing with tick counter */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if !MCUC1_CONFIG_PEX_SDK_USED + /*! \todo */ + #define LPTMR0_BASE_PTR LPTMR0 /* low power timer address base */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LPTMR0_IRQn /* low power timer IRQ number */ + #define ENABLE_TICK_COUNTER() LPTMR_StartTimer(LPTMR0_BASE_PTR); LPTMR_EnableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define DISABLE_TICK_COUNTER() LPTMR_StopTimer(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() LPTMR_StopTimer(LPTMR0_BASE_PTR); LPTMR_DisableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define ACKNOWLEDGE_TICK_ISR() LPTMR_ClearStatusFlags(LPTMR0_BASE_PTR, kLPTMR_TimerCompareFlag); + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define ENABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_ENABLE); LPTMR_PDD_EnableInterrupt(LPTMR0_BASE_PTR) + #define DISABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_DISABLE); LPTMR_PDD_DisableInterrupt(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() DISABLE_TICK_COUNTER() /* CNR is reset when the LPTMR is disabled or counter register overflows */ + #define ACKNOWLEDGE_TICK_ISR() LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR) + #if defined(LDD_ivIndex_INT_LPTimer) /* Earlier version of Processor Expert use this vector name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTimer + #elif defined(LDD_ivIndex_INT_LPTMR0) /* Newer versions (Processor Expert for Kinetis v3.0.1 uses this name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTMR0 + #else + #error "Unknown Low Power Timer Interrupt Number?" + #endif + #endif +#else + #define ENABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT + #define DISABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT + #define RESET_TICK_COUNTER_VAL() portNVIC_SYSTICK_CURRENT_VALUE_REG = 0 /*portNVIC_SYSTICK_LOAD_REG*/ + #define ACKNOWLEDGE_TICK_ISR() /* not needed */ +#endif + +typedef unsigned long TickCounter_t; /* enough for 24 bit Systick */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TICK_NOF_BITS 16 + #define COUNTS_UP 1 /* LPTMR is counting up */ + #if !MCUC1_CONFIG_PEX_SDK_USED + #define SET_TICK_DURATION(val) LPTMR_SetTimerPeriod(LPTMR0_BASE_PTR, val); + #define GET_TICK_DURATION() LPTMR0_BASE_PTR->CNR /*! \todo SDK has no access method for this */ + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_GetCurrentTimerCount(LPTMR0_BASE_PTR) + #else + #define SET_TICK_DURATION(val) LPTMR_PDD_WriteCompareReg(LPTMR0_BASE_PTR, val) + #define GET_TICK_DURATION() LPTMR_PDD_ReadCompareReg(LPTMR0_BASE_PTR) + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_PDD_ReadCounterReg(LPTMR0_BASE_PTR) + #endif +#else + #define TICK_NOF_BITS 24 + #define COUNTS_UP 0 /* SysTick is counting down to zero */ + #define SET_TICK_DURATION(val) portNVIC_SYSTICK_LOAD_REG = val + #define GET_TICK_DURATION() portNVIC_SYSTICK_LOAD_REG + #define GET_TICK_CURRENT_VAL(addr) *(addr)=portNVIC_SYSTICK_CURRENT_VALUE_REG +#endif + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ/configTICK_RATE_HZ) +#else + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_CLOCK_HZ/configTICK_RATE_HZ) +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + unsigned int SEGGER_SYSVIEW_TickCnt; /* tick counter for Segger SystemViewer */ +#endif + +#if configUSE_TICKLESS_IDLE + #define UL_TIMER_COUNTS_FOR_ONE_TICK ((TickCounter_t)(TIMER_COUNTS_FOR_ONE_TICK)) +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define TICKLESS_DISABLE_INTERRUPTS() __asm volatile("cpsid i") /* disable interrupts. Note that the wfi (wait for interrupt) instruction later will still be able to wait for interrupts! */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm volatile("cpsie i") /* re-enable interrupts. */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define TICKLESS_DISABLE_INTERRUPTS() __asm("sei"); /* disable interrupts */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm("cli"); /* re-enable interrupts */ +#else + #define TICKLESS_DISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /* this disables interrupts! Make sure they are re-enabled in vOnPreSleepProcessing()! */ + #define TICKLESS_ENABLE_INTERRUPTS() portENABLE_INTERRUPTS() /* re-enable interrupts */ +#endif + + #if 1 /* using ARM SysTick Timer */ + #if configSYSTICK_USE_LOW_POWER_TIMER + /* using Low Power Timer */ + #if CONFIG_PEX_SDK_USEDMCUC1_CONFIG_PEX_SDK_USED + #define LPTMR_CSR_TCF_MASK 0x80u + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR0_BASE_PTR->CSR&LPTMR_CSR_TCF_MASK)!=0/*! \todo */ /* returns TRUE if tick interrupt had fired */ + #else + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR_PDD_GetInterruptFlag(LPTMR0_BASE_PTR)!=0) /* returns TRUE if tick interrupt had fired */ + #endif + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #else + /* using directly SysTick Timer */ + #define TICK_INTERRUPT_HAS_FIRED() ((portNVIC_SYSTICK_CTRL_REG&portNVIC_SYSTICK_COUNT_FLAG_BIT)!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #endif + #else + /* using global variable to find out if interrupt has fired */ + volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ + #define TICK_INTERRUPT_HAS_FIRED() (portTickCntr!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() portTickCntr=0 + #define TICK_INTERRUPT_FLAG_SET() portTickCntr=1 + #endif +#endif /* configUSE_TICKLESS_IDLE == 1 */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * resolution of the tick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the tick timer is stopped (low + * power functionality only). + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t ulStoppedTimerCompensation = 0; /* number of timer ticks to compensate */ + #define configSTOPPED_TIMER_COMPENSATION 45UL /* number of CPU cycles to compensate. ulStoppedTimerCompensation will contain the number of timer ticks. */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* Flag indicating that the tick counter interval needs to be restored back to + * the normal setting. Used when woken up from a low power mode using the LPTMR. + */ +#if configUSE_TICKLESS_IDLE && configSYSTICK_USE_LOW_POWER_TIMER + static uint8_t restoreTickInterval = 0; /* used to flag in tick ISR that compare register needs to be reloaded */ +#endif + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portINITIAL_FORMAT_VECTOR ((portSTACK_TYPE)0x4000) + #define portINITIAL_STATUS_REGISTER ((portSTACK_TYPE)0x2000) /* Supervisor mode set. */ +#endif + +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Constants required to manipulate the core. + * SysTick register: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html + * Registers first... + */ +#define portNVIC_SYSTICK_CTRL_REG (*((volatile unsigned long *)0xe000e010)) /* SYST_CSR, SysTick Control and Status Register */ +#define portNVIC_SYSTICK_LOAD_REG (*((volatile unsigned long *)0xe000e014)) /* SYST_RVR, SysTick reload value register */ +#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile unsigned long *)0xe000e018)) /* SYST_CVR, SysTick current value register */ +#define portNVIC_SYSTICK_CALIB_VALUE_REG (*((volatile unsigned long *)0xe000e01C)) /* SYST_CALIB, SysTick calibration value register */ +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_COUNT_FLAG_BIT (1UL<<16UL) /* returns 1 if timer counted to 0 since the last read of the register */ +#if configSYSTICK_USE_CORE_CLOCK + #define portNVIC_SYSTICK_CLK_BIT (1UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#else + #define portNVIC_SYSTICK_CLK_BIT (0UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#endif +#define portNVIC_SYSTICK_INT_BIT (1UL<<1UL) /* SysTick interrupt enable bit */ +#define portNVIC_SYSTICK_ENABLE_BIT (1UL<<0UL) /* SysTick enable bit */ + +/* Constants required to manipulate the NVIC: */ +#define portNVIC_INT_CTRL ((volatile unsigned long*)0xe000ed04) /* interrupt control and state register (ICSR) */ +#define portNVIC_PENDSVSET_BIT (1UL<<28UL) /* bit 28 in portNVIC_INT_CTRL (PENDSVSET), see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihfaaha.html */ +#define portNVIC_PENDSVCLEAR_BIT (1UL<<27UL) /* bit 27 in portNVIC_INT_CTRL (PENDSVCLR) */ +#define portNVIC_PEND_SYSTICK_SET_BIT (1UL<<26UL) /* bit 26 in portNVIC_INT_CTRL (PENDSTSET) */ +#define portNVIC_PEND_SYSTICK_CLEAR_BIT (1UL<<25UL) /* bit 25 in portNVIC_INT_CTRL (PENDSTCLR) */ + +#define portNVIC_SYSPRI2 ((volatile unsigned long*)0xe000ed1c) /* system handler priority register 2 (SHPR2), used for SVCall priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SVCALL_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SVCall interrupt (in portNVIC_SYSPRI2) */ + +#define portNVIC_SYSPRI3 ((volatile unsigned long*)0xe000ed20) /* system handler priority register 3 (SHPR3), used for SysTick and PendSV priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SYSTICK_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SysTick interrupt (in portNVIC_SYSPRI3) */ +#define portNVIC_PENDSV_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<16) /* priority of PendableService interrupt (in portNVIC_SYSPRI3) */ + +#define portNVIC_SYSPRI7 ((volatile unsigned long*)0xe000e41c) /* system handler priority register 7, PRI_28 is LPTMR */ +#define portNVIC_LP_TIMER_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<0) /* priority of low power timer interrupt */ + +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT +#define IRQn_Type int +#define __NVIC_PRIO_BITS configPRIO_BITS +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; +#else /* M0+ */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; +#endif + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + +/** \brief Set Interrupt Priority + The function sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +static void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); /* set Priority for device specific Interrupts */ +#else /* M0+ */ + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); /* set Priority for device specific Interrupts */ +#endif +} + +/** \brief Enable External Interrupt + The function enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +static void NVIC_EnableIRQ(IRQn_Type IRQn) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +#else /* M0+ */ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +#endif +} +#endif /* configSYSTICK_USE_LOW_POWER_TIMER */ + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR (0x01000000) +#define portINITIAL_EXEC_RETURN (0xfffffffd) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED (0x03) +#define portINITIAL_CONTROL_IF_PRIVILEGED (0x02) + +#if configENABLE_FPU + /* Constants required to manipulate the VFP. */ + #define portFPCCR ((volatile unsigned long *)0xe000ef34) /* Floating point context control register. */ + #define portASPEN_AND_LSPEN_BITS (0x3UL<<30UL) +#endif +#endif +/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). + This will be set to 0 prior to the first task being started. */ +/* Each task maintains its own interrupt status in the critical nesting variable. */ +static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; + +#if INCLUDE_vTaskEndScheduler +#include +static jmp_buf xJumpBuf; /* Used to restore the original context when the scheduler is ended. */ +#endif +/*-----------------------------------------------------------*/ +void prvTaskExitError(void) { + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT(uxCriticalNesting == ~0UL); + portDISABLE_INTERRUPTS(); + for(;;) { + /* wait here */ + } +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) /* ARM M4(F)/M7/M33 core */ +__asm uint32_t ulPortSetInterruptMask(void) { + PRESERVE8 + + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) +__asm void vPortClearInterruptMask(uint32_t ulNewMask) { + PRESERVE8 + + msr basepri, r0 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if configENABLE_MPU +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged) { +#else +StackType_t *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { +#endif + /* Simulate the stack frame as it would be created by a context switch interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts, and to ensure alignment. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; +#if configENABLE_MPU + *pxTopOfStack = ((StackType_t)pxCode)&portSTART_ADDRESS_MASK; /* PC */ +#else + *pxTopOfStack = ((StackType_t)pxCode); /* PC */ +#endif + pxTopOfStack--; + *pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialization. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = (portSTACK_TYPE)pvParameters; /* R0 */ + +#if configENABLE_FPU /* has floating point unit */ + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; +#endif +#if configENABLE_MPU + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4 plus privilege level */ + if (xRunPrivileged == pdTRUE) { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } else { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } +#else + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ +#endif + return pxTopOfStack; +} + +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_S08_FSL) || (configCOMPILER==configCOMPILER_S12_FSL) +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma MESSAGE DISABLE C20000 /* dead code detected */ + #pragma NO_RETURN + #pragma CODE_SEG __NEAR_SEG NON_BANKED +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma NO_RETURN +#endif + +static portBASE_TYPE xBankedStartScheduler(void) { + /* Restore the context of the first task. */ + portRESTORE_CONTEXT(); /* Simulate the end of an interrupt to start the scheduler off. */ + /* Should not get here! */ + return pdFALSE; +} + +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma CODE_SEG DEFAULT + #pragma MESSAGE DEFAULT C1404 /* return expected */ + #pragma MESSAGE DEFAULT C20000 /* dead code detected */ +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DEFAULT C1404 /* return expected */ +#endif +#endif +/*-----------------------------------------------------------*/ +#if configUSE_TICKLESS_IDLE == 1 +void FRTOS1_vOnPreSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +void FRTOS1_vOnPostSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +#if (configCOMPILER==configCOMPILER_ARM_GCC) || (configCOMPILER==configCOMPILER_ARM_KEIL) +__attribute__((weak)) +#endif +void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { + unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements; + TickCounter_t tmp; /* because of how we get the current tick counter */ + bool tickISRfired; + uint32_t tickDuration; + +#if configSYSTICK_USE_LOW_POWER_TIMER + /* if we wait for the tick interrupt, do not enter low power again below */ + if (restoreTickInterval!=0) { + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* default example code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + return; + } +#endif + + /* Make sure the tick timer reload value does not overflow the counter. */ + if(xExpectedIdleTime > xMaximumPossibleSuppressedTicks) { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the tick timer momentarily. The time the counter is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else /* using normal timer or SysTick */ + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. This code will execute part way through one + * of the tick periods. + */ + /* -1UL is used because this code will execute part way through one of the tick periods */ +#if COUNTS_UP + ulReloadValue = (UL_TIMER_COUNTS_FOR_ONE_TICK*xExpectedIdleTime); + #if configSYSTICK_USE_LOW_POWER_TIMER + if (ulReloadValue > 0) { /* make sure it does not underflow */ + ulReloadValue -= 1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + } + #endif + if (tmp!=0 && ulReloadValue>=tmp) { /* make sure it does not underflow */ + ulReloadValue -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + ulReloadValue = tmp+(UL_TIMER_COUNTS_FOR_ONE_TICK*(xExpectedIdleTime-1UL)); +#endif + if (ulStoppedTimerCompensation!=0 && ulReloadValue>ulStoppedTimerCompensation) { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. + */ + TICKLESS_DISABLE_INTERRUPTS(); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. + */ + if (eTaskConfirmSleepModeStatus()==eAbortSleep) { + /* Must restore the duration before re-enabling the timers */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK-1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tmp!=0 && tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + tickDuration = tmp; +#endif + SET_TICK_DURATION(tickDuration); + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICKLESS_ENABLE_INTERRUPTS(); + } else { + SET_TICK_DURATION(ulReloadValue); /* Set the new reload value. */ + RESET_TICK_COUNTER_VAL(); /* Reset the counter. */ + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICK_INTERRUPT_FLAG_RESET(); /* reset flag so we know later if it has fired */ + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. + */ + + /* CPU *HAS TO WAIT* in the sequence below for an interrupt. If vOnPreSleepProcessing() is not used, a default implementation is provided */ + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* example/default code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + /* ---------------------------------------------------------------------------- + * Here the CPU *HAS TO BE* low power mode, waiting to wake up by an interrupt + * ----------------------------------------------------------------------------*/ + FRTOS1_vOnPostSleepProcessing(xExpectedIdleTime); /* process post-low power actions */ + /* Stop tick counter. Again, the time the tick counter is stopped for is + * accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ + tickISRfired = (bool)TICK_INTERRUPT_HAS_FIRED(); /* need to check Interrupt flag here, as might be modified below */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + TICKLESS_ENABLE_INTERRUPTS();/* Re-enable interrupts */ + if (tickISRfired) { + /* The tick interrupt has already executed, and the timer + * count reloaded with the modulo/match value. + * Reset the counter register with whatever remains of + * this tick period. + */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; + } + if (tickDuration > 1) { + /*! \todo Need to rethink this one! */ + //tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + vTaskStepTick(1); + } +#else + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)-(ulReloadValue-tmp); +#endif + SET_TICK_DURATION(tickDuration); + /* The tick interrupt handler will already have pended the tick + * processing in the kernel. As the pending tick will be + * processed as soon as this function exits, the tick value + * maintained by the tick is stepped forward by one less than the + * time spent waiting. + */ + ulCompleteTickPeriods = xExpectedIdleTime-1UL; /* -1 because we already added a completed tick from the tick interrupt */ + } else { + /* Something other than the tick interrupt ended the sleep. + * Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part ticks). + */ +#if COUNTS_UP + ulCompletedSysTickIncrements = tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = (((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-1)-ulCompletedSysTickIncrements; + if (tickDuration > 1) { + tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + if (tickDuration > 1) { /* check for underflow */ + tickDuration -= 1; + } + vTaskStepTick(1); + } +#else + ulCompletedSysTickIncrements = (xExpectedIdleTime*UL_TIMER_COUNTS_FOR_ONE_TICK)-tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = ((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-ulCompletedSysTickIncrements; +#endif + SET_TICK_DURATION(tickDuration); + } + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. + */ + RESET_TICK_COUNTER_VAL(); + portENTER_CRITICAL(); + { + ENABLE_TICK_COUNTER(); + if (ulCompleteTickPeriods>0) { + vTaskStepTick(ulCompleteTickPeriods); + } +#if configSYSTICK_USE_LOW_POWER_TIMER + /* The compare register of the LPTMR should not be modified when the + * timer is running, so wait for the next tick interrupt to change it. + */ + if (tickDuration != (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)) { /* minus one because of LPTMR way to trigger interrupts */ + if (tickISRfired) { + /* The pending tick interrupt will be immediately processed after + * exiting this function so we need to delay the change of the tick + * duration until the one after that. + */ + restoreTickInterval = 2; + } else { + /* Notify the tick interrupt that the tick duration needs to be + * changed back to the normal setting. + */ + restoreTickInterval = 1; + } + } else { + /* If the duration is the standard full tick, then there's no reason + * to stop and restart LPTMR in the tick interrupt. + */ + restoreTickInterval = 0; + } +#else + /* The systick has a load register that will automatically be used + * when the counter counts down to zero. + */ + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); +#endif + } + portEXIT_CRITICAL(); + } +} +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ +static void vPortInitTickTimer(void) { +#if configUSE_TICKLESS_IDLE == 1 +{ +#if TICK_NOF_BITS==32 + xMaximumPossibleSuppressedTicks = 0xffffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 32bit timer register */ +#elif TICK_NOF_BITS==24 + xMaximumPossibleSuppressedTicks = 0xffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 24bit timer register */ +#elif TICK_NOF_BITS==16 + xMaximumPossibleSuppressedTicks = 0xffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 16bit timer register */ +#elif TICK_NOF_BITS==8 + xMaximumPossibleSuppressedTicks = 0xffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 8bit timer register */ +#else + error "unknown configuration!" +#endif +#if configSYSTICK_USE_LOW_POWER_TIMER + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ); +#else + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_CLOCK_HZ); +#endif +} +#endif /* configUSE_TICKLESS_IDLE */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* SIM_SCGx: enable clock to LPTMR */ +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); + + /* LPTRM0_CSR: clear TCF (Timer compare Flag) with writing a one to it */ + LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR); + + /* LPTMR_PSR: configure prescaler, bypass and clock source */ + /* PBYP PCS + * ERCLK32 1 10 + * LPO_1kHz 1 01 + * ERCLK 0 00 + * IRCLK 1 00 + */ + LPTMR_PDD_SelectPrescalerSource(LPTMR0_BASE_PTR, LPTMR_PDD_SOURCE_LPO1KHZ); + LPTMR_PDD_EnablePrescalerBypass(LPTMR0_BASE_PTR, LPTMR_PDD_BYPASS_ENABLED); +#elif MCUC1_CONFIG_NXP_SDK_2_0_USED + /*! \todo */ + { + lptmr_config_t config; + + LPTMR_GetDefaultConfig(&config); + LPTMR_Init(LPTMR0_BASE_PTR, &config); + } +#endif + /* set timer interrupt priority in IP[] and enable it in ISER[] */ + NVIC_SetPriority(configLOW_POWER_TIMER_VECTOR_NUMBER, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); + NVIC_EnableIRQ(configLOW_POWER_TIMER_VECTOR_NUMBER); /* enable IRQ in NVIC_ISER[] */ +#else /* use normal SysTick Counter */ + *(portNVIC_SYSPRI3) |= portNVIC_SYSTICK_PRI; /* set priority of SysTick interrupt */ +#endif + /* Configure timer to interrupt at the requested rate. */ + DISABLE_TICK_COUNTER(); /* disable the timer, just in case it is already running */ + SET_TICK_DURATION(TIMER_COUNTS_FOR_ONE_TICK-1UL); /* set tick period */ + RESET_TICK_COUNTER_VAL(); /* reset counter so it starts properly */ + ENABLE_TICK_COUNTER(); /* let it run */ +} +/*-----------------------------------------------------------*/ +static void vPortStartTickTimer(void) { + ENABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +void vPortStopTickTimer(void) { + DISABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +#if configENABLE_FPU /* has floating point unit */ +void vPortEnableVFP(void) { +#if 1 /* configLTO_HELPER: using implementation in C which is portable */ + #define CPACR_REG_MEM ((volatile int*)0xE000ED88) /* location of the CPACR register */ + + *CPACR_REG_MEM |= (0xf<<20); /* Enable CP10 and CP11 coprocessors */ +#else /* below is the original assembly code which fails with -flto because of the constant load */ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +#endif +} +#endif /* M4/M7 */ +/*-----------------------------------------------------------*/ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) && (configASSERT_DEFINED == 1) + /* Constants required to check the validity of an interrupt priority. */ + #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) + #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) + #define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) + #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) + #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) + #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) + #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + #define portPRIGROUP_SHIFT ( 8UL ) + + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +BaseType_t xPortStartScheduler(void) { + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) */ /* ARM M4(F)/M7 core */ + +#if configCPU_FAMILY==configCPU_FAMILY_ARM_M7F + /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 r0p1 port. */ + #define portCPUID (*((volatile uint32_t*)0xE000ed00)) + #define portCORTEX_M7_r0p0_ID (0x410FC270UL) + #define portCORTEX_M7_r0p1_ID (0x410FC271UL) /* this one will require a special port! Writing to the BASEPRIO is not taking effect immediately, even with memory barrier instructions. Workaround: globally disable interrupts before writing to BASEPRIO, then write, then use memory barrier. */ + #define portCORTEX_M7_r0p2_ID (0x410FC272UL) /* is present on the TWR-KV57F220M */ + + configASSERT(portCPUID!=portCORTEX_M7_r0p1_ID); /* this one will require a special port! */ +#endif + + /* Make PendSV, SVCall and SysTick the lowest priority interrupts. SysTick priority will be set in vPortInitTickTimer(). */ +#if 0 /* do NOT set the SVCall priority */ + /* why: execution of an SVC instruction at a priority equal or higher than SVCall can cause a hard fault (at least on Cortex-M4), + see https://community.freescale.com/thread/302511 */ + *(portNVIC_SYSPRI2) |= portNVIC_SVCALL_PRI; /* set priority of SVCall interrupt */ +#endif + *(portNVIC_SYSPRI3) |= portNVIC_PENDSV_PRI; /* set priority of PendSV interrupt */ + uxCriticalNesting = 0; /* Initialize the critical nesting count ready for the first task. */ + vPortInitTickTimer(); /* initialize tick timer */ + vPortStartTickTimer(); /* start tick timer */ +#if configENABLE_FPU /* has floating point unit */ + vPortEnableVFP(); /* Ensure the VFP is enabled - it should be anyway */ + *(portFPCCR) |= portASPEN_AND_LSPEN_BITS; /* Lazy register save always */ +#endif +#if INCLUDE_vTaskEndScheduler + if(setjmp(xJumpBuf) != 0 ) { + /* here we will get in case of a call to vTaskEndScheduler() */ + __asm volatile( + " movs r0, #0 \n" /* Reset CONTROL register and switch back to the MSP stack. */ + " msr CONTROL, r0 \n" + " dsb \n" + " isb \n" + ); + return pdFALSE; + } +#endif + vPortStartFirstTask(); /* Start the first task. */ + /* Should not get here! */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ +void vPortEndScheduler(void) { + vPortStopTickTimer(); + vPortInitializeHeap(); + uxCriticalNesting = 0xaaaaaaaa; + /* Jump back to the processor state prior to starting the + scheduler. This means we are not going to be using a + task stack frame so the task can be deleted. */ +#if INCLUDE_vTaskEndScheduler + longjmp(xJumpBuf, 1); +#else + for(;;){} /* wait here */ +#endif +} +/*-----------------------------------------------------------*/ +void vPortEnterCritical(void) { +/* + * Disable interrupts before incrementing the count of critical section nesting. + * The nesting count is maintained so we know when interrupts should be + * re-enabled. Once interrupts are disabled the nesting count can be accessed + * directly. Each task maintains its own nesting count. + */ + portDISABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + uxCriticalNesting++; +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ + #define portVECTACTIVE_MASK (0xFFUL) + + configASSERT(((*portNVIC_INT_CTRL) & portVECTACTIVE_MASK)==0); + } +#endif + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +void vPortExitCritical(void) { + /* Interrupts are disabled so we can access the nesting count directly. If the + * nesting is found to be 0 (no nesting) then we are leaving the critical + * section and interrupts can be re-enabled. + */ + uxCriticalNesting--; + if (uxCriticalNesting == 0) { + portENABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ +void vPortYieldFromISR(void) { + /* Set a PendSV to request a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT; + /* Barriers are normally not required but do ensure the code is completely + within the specified behavior for the architecture. */ + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +/* return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time */ + uint32_t uxGetTickCounterValue(void) { + long val; + + GET_TICK_CURRENT_VAL(&val); + return val; +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + /* this is how we get here: + RTOSTICKLDD1_Interrupt: + push {r4, lr} + ... RTOSTICKLDD1_OnCounterRestart + bl RTOSTICKLDD1_OnCounterRestart -> push {r4,lr} + pop {r4, lr} mov r4,r0 + bl vPortTickHandler + pop {r4,pc} + */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + portDISABLE_INTERRUPTS(); /* disable interrupts */ +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + taskYIELD(); + } + portENABLE_INTERRUPTS(); /* enable interrupts again */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + ACKNOWLEDGE_TICK_ISR(); +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); /* disable interrupts */ + traceISR_ENTER(); +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + traceISR_EXIT_TO_SCHEDULER(); + taskYIELD(); + } else { + traceISR_EXIT(); + } + portENABLE_INTERRUPTS(); /* re-enable interrupts */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_DSC_FSL) +void vPortStartFirstTask(void) { + /* Restore the context of the first task to run. */ + portRESTORE_CONTEXT(); + /* Simulate the end of the yield function. */ + __asm(rts); +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +__asm void vPortStartFirstTask(void) { +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* Use the NVIC offset register to locate the stack. */ +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 +#endif + /* Globally enable interrupts. */ + cpsie i + /* Call SVC to start the first task. */ + svc 0 + nop + nop + nop +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + extern pxCurrentTCB; + + PRESERVE8 + + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + + ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */ + ldr r1, [r3] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + movs r0, #2 /* Switch to the psp stack. */ + msr CONTROL, r0 + isb + pop {r0-r5} /* Pop the registers that are saved automatically. */ + mov lr, r5 /* lr is now in r5. */ + pop {r3} /* The return address is now in r3. */ + pop {r2} /* Pop and discard the XPSR. */ + cpsie i /* The first task has its context and interrupts can be enabled. */ + bx r3 /* Finally, jump to the user defined task code. */ + + ALIGN +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +/* Need the 'noinline', as latest gcc with -O3 tries to inline it, and gives error message: "Error: symbol `pxCurrentTCBConst2' is already defined" */ +__attribute__((noinline)) +void vPortStartFirstTask(void) { +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* only needed for openOCD or Segger FreeRTOS thread awareness. It needs the symbol uxTopUsedPriority present after linking */ + { + extern volatile const int uxTopUsedPriority; + __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd; + dummy_value_for_openocd = uxTopUsedPriority; + } +#endif +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) + /* reference FreeRTOSDebugConfig, otherwise it might get removed by the linker or optimizations */ + { + extern const uint8_t FreeRTOSDebugConfig[]; + if (FreeRTOSDebugConfig[0]==0) { /* just use it, so the linker cannot remove FreeRTOSDebugConfig[] */ + for(;;); /* FreeRTOSDebugConfig[0] should always be non-zero, so this should never happen! */ + } + } +#endif +#if configHEAP_SCHEME_IDENTIFICATION + extern const uint8_t freeRTOSMemoryScheme; /* constant for NXP Kernel Awareness to indicate heap scheme */ + if (freeRTOSMemoryScheme>100) { /* reference/use variable so it does not get optimized by the linker */ + for(;;); + } +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler +#if configLTO_HELPER /* with -flto, we cannot load the constant directly, otherwise we get "Error: offset out of range" with "lto-wrapper failed" */ + " mov r0, #0xE0000000 \n" /* build the constant 0xE000ED08. First load the upper 16 bits */ + " mov r1, #0xED00 \n" /* next load part of the lower 16 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED00 in R0 */ + " mov r1, #0x08 \n" /* next load the lowest 8 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED08 in R0 */ +#else + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ +#endif + " ldr r0, [r0] \n" /* load address of vector table */ + " ldr r0, [r0] \n" /* load first entry of vector table which is the reset stack pointer */ + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ +#endif + " cpsie i \n" /* Globally enable interrupts. */ + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + __asm volatile( + " ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */ + " ldr r3, [r2] \n" + " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " movs r0, #2 \n" /* Switch to the psp stack. */ + " msr CONTROL, r0 \n" + " isb \n" + " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ + " mov lr, r5 \n" /* lr is now in r5. */ + " pop {r3} \n" /* Return address is now in r3. */ + " pop {r2} \n" /* Pop and discard XPSR. */ + " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ + " bx r3 \n" /* Finally, jump to the user defined task code. */ + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB" + ); +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* \todo: r14, check http://sourceforge.net/p/freertos/discussion/382005/thread/a9406af1/?limit=25#3bc7 */ +#else + ldmia r0!, {r4-r11} +#endif + msr psp, r0 + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 +#if configENABLE_FPU +#else + orr r14, r14, #13 +#endif + bx r14 +} +/*-----------------------------------------------------------*/ +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ and Keil */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + /* This function is no longer used, but retained for backward + compatibility. */ +} +#endif +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void SVC_Handler(void) { +#else +__attribute__ ((naked)) void vPortSVCHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +__asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + /* pop the core registers */ +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" +#else + " ldmia r0!, {r4-r11} \n" +#endif + " msr psp, r0 \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" +#if configENABLE_FPU +#else + " orr r14, r14, #13 \n" +#endif + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* This function is no longer used, but retained for backward + compatibility. */ +#endif +} +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] +#if configENABLE_FPU + tst r14, #0x10 /* Is the task using the FPU context? If so, push high vfp registers. */ + it eq + vstmdbeq r0!, {s16-s31} + + stmdb r0!, {r4-r11, r14} /* save remaining core registers */ +#else + stmdb r0!, {r4-r11} /* Save the core registers. */ +#endif + str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ + stmdb sp!, {r3, r14} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. */ + ldr r0, [r1] +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* Pop the core registers */ + tst r14, #0x10 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + it eq + vldmiaeq r0!, {s16-s31} +#else + ldmia r0!, {r4-r11} /* Pop the core registers. */ +#endif + msr psp, r0 + bx r14 + nop +} +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Keil: Cortex M0+ */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] + + subs r0, #32 /* Make space for the remaining low registers. */ + str r0, [r2] /* Save the new top of stack. */ + stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ + mov r4, r8 /* Store the high registers. */ + mov r5, r9 + mov r6, r10 + mov r7, r11 + stmia r0!, {r4-r7} + + push {r3, r14} + cpsid i + bl vTaskSwitchContext + cpsie i + pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ + + ldr r1, [r2] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #16 /* Move to the high registers. */ + ldmia r0!, {r4-r7} /* Pop the high registers. */ + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + + msr psp, r0 /* Remember the new top of stack for the task. */ + + subs r0, #32 /* Go back for the low registers that are not automatically restored. */ + ldmia r0!, {r4-r7} /* Pop low registers. */ + + bx r3 + nop +} +#endif +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if configGDB_HELPER +/* prototypes to avoid compiler warnings */ +__attribute__ ((naked)) void vPortPendSVHandler_native(void); +__attribute__ ((naked)) void PendSV_Handler_jumper(void); + +__attribute__ ((naked)) void vPortPendSVHandler_native(void) { +#elif !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB" + ); +#endif +} + +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* This is only really needed for debugging with openOCD: + * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer + * present in the kernel, so it has to be supplied by other means for + * OpenOCD's threads awareness. + * + * Add this file to your project, and, if you're using --gc-sections, + * ``--undefined=uxTopUsedPriority'' (or + * ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final + * linking) to your LDFLAGS; same with all the other symbols you need. + */ + volatile const int + #ifdef __GNUC__ + __attribute__((used)) + #endif + uxTopUsedPriority = configMAX_PRIORITIES-1; +#endif + +#if configGDB_HELPER /* if GDB debug helper is enabled */ +/* Credits to: + * - Artem Pisarneko for his initial contribution + * - Prasana for the PendSVHandler updates + * - Geoffrey Wossum for the Cortex-M4 contribution + */ + +/* Switch control variable: + * 0 - no hook installed (normal execution), + * 1 - hook installation performed, + * 2 - following hooked switches + */ +int volatile dbgPendSVHookState = 0; +/* Requested target task handle variable */ +void *volatile dbgPendingTaskHandle; + +const int volatile dbgFreeRTOSConfig_suspend_value = INCLUDE_vTaskSuspend; +const int volatile dbgFreeRTOSConfig_delete_value = INCLUDE_vTaskDelete; + +__attribute__ ((naked)) void PendSV_Handler_jumper(void) { + __asm volatile("b vPortPendSVHandler_native \n"); +} + +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configGDB_HELPER + " ldr r1, _dbgPendSVHookState \n" /* Check hook installed */ + " ldr r0, [r1] \n" + " cmp r0, #0 \n" + " beq PendSV_Handler_jumper \n" /* if no hook installed then jump to native handler, else proceed... */ + " cmp r0, #1 \n" /* check whether hook triggered for the first time... */ + " bne dbg_switch_to_pending_task \n" /* if not so, then jump to switching right now, otherwise current task context must be saved first... */ + " mov r0, #2 \n" /* mark hook after triggered for the first time */ + " str r0, [r1] \n" +#endif /* configGDB_HELPER */ + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" +#if configGDB_HELPER + "dbg_switch_to_pending_task: \n" + " ldr r3, _dbgPendingTaskHandle \n" /* --> Load task handle going to switch to <-- */ +#endif /* configGDB_HELPER */ + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" +#if configGDB_HELPER + " bkpt \n" /* <-- here debugger stops and steps out to target task context */ +#endif /* configGDB_HELPER */ + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB \n" +#if configGDB_HELPER + "_dbgPendSVHookState: .word dbgPendSVHookState \n" + "_dbgPendingTaskHandle: .word dbgPendingTaskHandle \n" + ".word dbgFreeRTOSConfig_suspend_value \n" /* force keep these symbols from cutting away by linker garbage collector */ + ".word dbgFreeRTOSConfig_delete_value \n" +#endif + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB" + ); +#endif +} + +#endif /* configGDB_HELPER */ + +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + +#if configCOMPILER==configCOMPILER_ARM_KEIL +__asm uint32_t vPortGetIPSR(void) { + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +#endif + +#if( configASSERT_DEFINED == 1 ) + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + ulCurrentInterrupt = vPortGetIPSR(); + #else + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + #endif + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +#endif /* ARM M4(F) core */ + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/portTicks.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portTicks.h new file mode 100644 index 0000000..f69c990 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portTicks.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PORTTICKS_H_ +#define PORTTICKS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Interface header file to the Processor Expert Tick counter. + * This file is used to access the interface, especially for performance + * counters (e.g. for Percepio Trace). + * That way the a module can interface this wrapper header file instead + * of one of the standard FreeRTOS header files. + */ +#include "MCUC1.h" /* include SDK and API used */ + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "Cpu.h" /* include CPU module because of dependency to CPU clock rate */ +#endif +#include "FreeRTOSConfig.h" +#include "portmacro.h" + +#if !MCUC1_CONFIG_PEX_SDK_USED + extern uint32_t SystemCoreClock; /* in Kinetis SDK, this contains the system core clock speed */ +#endif + +/*! + * \brief Return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time + * \return Tick counter value. The value is reset at tick interrupt time. + * */ +uint32_t uxGetTickCounterValue(void); + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define FREERTOS_HWTC_DOWN_COUNTER 0 /* LPTM is counting up */ + #define FREERTOS_HWTC_PERIOD ((1000/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ)-1UL) /* counter is incrementing from zero to this value */ +#else + #define FREERTOS_HWTC_DOWN_COUNTER 1 /* SysTick is counting down */ + #define FREERTOS_HWTC_PERIOD ((configCPU_CLOCK_HZ/configTICK_RATE_HZ)-1UL) /* counter is decrementing from this value to zero */ +#endif + +#if configUSE_TICKLESS_IDLE == 1 + extern volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ +#endif + +#define FREERTOS_HWTC_FREQ_HZ configTICK_RATE_HZ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* using Percepio Trace */ +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_PROCESSOR_EXPERT) + /* tick information for Percepio Trace */ + + /* undefine previous values, where dummy anyway: make sure this header file is included last! */ + #undef TRC_HWTC_COUNT_DIRECTION + #undef TRC_HWTC_PERIOD + #undef TRC_HWTC_DIVISOR + #undef TRC_HWTC_COUNT + + #if FREERTOS_HWTC_DOWN_COUNTER + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is decrementing from this value to zero */ + #else + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is incrementing from zero to this value */ + #endif + + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #if configSYSTICK_USE_LOW_POWER_TIMER + #define TRC_HWTC_DIVISOR 1 /* divisor for slow counter tick value */ + #else + #define TRC_HWTC_DIVISOR 2 /* divisor for fast counter tick value */ + #endif + #else + #define TRC_HWTC_DIVISOR 1 + #endif + + #define TRC_HWTC_COUNT (uxGetTickCounterValue()) + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_IRQ_PRIORITY_ORDER 0 /* 0: lower IRQ prios mean higher priority, 1: otherwise */ + #define TRC_HWTC_FREQ_HZ FREERTOS_HWTC_FREQ_HZ +#endif +#endif /* configUSE_PERCEPIO_TRACE_HOOKS */ + +#ifdef __cplusplus +} +#endif + +#endif /* PORTTICKS_H_ */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/portable.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portable.h new file mode 100644 index 0000000..90ae895 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portable.h @@ -0,0 +1,183 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifndef portHAS_STACK_OVERFLOW_CHECKING + #define portHAS_STACK_OVERFLOW_CHECKING 0 +#endif + +#ifndef portARCH_NAME + #define portARCH_NAME NULL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #endif +#else + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #endif +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; +void vPortInitializeHeap(void) PRIVILEGED_FUNCTION; /* << EST */ + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/portasm.s b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portasm.s new file mode 100644 index 0000000..255f7c4 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portasm.s @@ -0,0 +1,28 @@ +/* file is intentionally empty as not needed for this GNU gcc FreeRTOS port */ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/portmacro.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portmacro.h new file mode 100644 index 0000000..b3299c6 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/portmacro.h @@ -0,0 +1,604 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOSConfig.h" +#include "projdefs.h" /* for pdFALSE, pdTRUE */ + +void vPortStopTickTimer(void); +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ +#ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. +#endif /* configENABLE_TRUSTZONE */ + +#if (configCOMPILER==configCOMPILER_S12_FSL) || (configCOMPILER==configCOMPILER_S08_FSL) + /* disabling some warnings as the RTOS sources are not that clean... */ + #pragma MESSAGE DISABLE C5909 /* assignment in condition */ + #pragma MESSAGE DISABLE C2705 /* possible loss of data */ + #pragma MESSAGE DISABLE C5905 /* multiplication with one */ + #pragma MESSAGE DISABLE C5904 /* division by one */ + #pragma MESSAGE DISABLE C5660 /* removed dead code */ + #pragma MESSAGE DISABLE C5917 /* removed dead assignment */ + #pragma MESSAGE DISABLE C4001 /* condition always FALSE */ +#endif +#if configCOMPILER==configCOMPILER_S12_FSL + #pragma MESSAGE DISABLE C12053 /* SP change not in debug information */ + #pragma MESSAGE DISABLE C12056 /* SP debug information incorrect */ +#endif + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portSTACK_TYPE unsigned long +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portSTACK_TYPE unsigned char +#endif +typedef portSTACK_TYPE StackType_t; + +#define portUSE_CUSTOM_BASE_TYPE 0 /* 1: use custom base type */ + +#if portUSE_CUSTOM_BASE_TYPE + #define portBASE_TYPE char /* custom port base type */ + typedef portBASE_TYPE BaseType_t; + typedef unsigned portBASE_TYPE UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBASE_TYPE long + typedef long BaseType_t; + typedef unsigned long UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBASE_TYPE char + typedef signed char BaseType_t; + typedef unsigned char UBaseType_t; +#endif + +#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)0xffffffff + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif /* 32bit architecture */ + +#endif + +#if( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); + extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* PRIVILEGED_FUNCTION */; +#endif /* configENABLE_TRUSTZONE */ + +#if( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; +#endif /* configENABLE_MPU */ + +/** + * @brief MPU specific constants. + */ +#if( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) +#else + #define portPRIVILEGE_BIT ( 0x0UL ) +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU +/*-----------------------------------------------------------*/ +/* MPU specific constants. */ + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU /* check values for LPC55xx! */ +/* Devices Region. */ +#define portDEVICE_REGION_START_ADDRESS ( 0x50000000 ) +#define portDEVICE_REGION_END_ADDRESS ( 0x5FFFFFFF ) + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ +#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ +#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ +#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ +#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ +#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ +#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ +#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) +#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) +#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) +#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) +#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + +#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ +typedef struct MPURegionSettings +{ + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ +} MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ +typedef struct MPU_SETTINGS +{ + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ +} xMPU_SETTINGS; + +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ +#define portSVC_ALLOCATE_SECURE_CONTEXT 0 +#define portSVC_FREE_SECURE_CONTEXT 1 +#define portSVC_START_SCHEDULER 2 +#define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ +/* Hardware specifics. */ +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define portBYTE_ALIGNMENT 8 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBYTE_ALIGNMENT 1 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH 1 /* stack grows from LOW to HIGH */ +#endif + +#define portTICK_PERIOD_MS ((TickType_t)1000/configTICK_RATE_HZ) +/*-----------------------------------------------------------*/ +/* Critical section management. */ +unsigned long ulPortSetIPL(unsigned portLONG); + +/* If set to 1, then this port uses the critical nesting count from the TCB rather than +maintaining a separate value and then saving this value in the task stack. */ +#define portCRITICAL_NESTING_IN_TCB 0 + + +extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR(void); +extern void vPortClearInterruptMaskFromISR(unsigned portBASE_TYPE); + + +#if configCOMPILER==configCOMPILER_DSC_FSL + /* for DSC, there is a possible skew after enable/disable Interrupts. */ + #define portPOST_ENABLE_DISABLE_INTERRUPTS() \ + asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); +#else + #define portPOST_ENABLE_DISABLE_INTERRUPTS() /* nothing special needed */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* Cortex M4/M7/M33 */ + #if (configCOMPILER==configCOMPILER_ARM_KEIL) + __asm uint32_t ulPortSetInterruptMask(void); + __asm void vPortClearInterruptMask(uint32_t ulNewMask); + + #define portSET_INTERRUPT_MASK() ulPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask(0) + #elif (configCOMPILER==configCOMPILER_ARM_GCC) + /* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ + #define portSET_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, %0 \n" \ + " msr basepri, r0 \n" \ + : /* no output operands */ \ + :"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) /* input */\ + :"r0" /* clobber */ \ + ) + /* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. + */ + #define portCLEAR_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, #0 \n" \ + " msr basepri, r0 \n" \ + : /* no output */ \ + : /* no input */ \ + :"r0" /* clobber */ \ + ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) /* IAR */ || (configCOMPILER==configCOMPILER_ARM_FSL) /* legacy FSL ARM Compiler */ + void vPortSetInterruptMask(void); /* prototype, implemented in portasm.s */ + void vPortClearInterruptMask(void); /* prototype, implemented in portasm.s */ + #define portSET_INTERRUPT_MASK() vPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask() + #else + #error "unknown compiler?" + #endif +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex-M0+ */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + #define portSET_INTERRUPT_MASK() __disable_irq() + #define portCLEAR_INTERRUPT_MASK() __enable_irq() + #else /* IAR, CW ARM or GNU ARM gcc */ + #define portSET_INTERRUPT_MASK() __asm volatile("cpsid i") + #define portCLEAR_INTERRUPT_MASK() __asm volatile("cpsie i") + #endif +#endif + +/* Critical section management. */ +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#if configCOMPILER==configCOMPILER_ARM_KEIL + #define portDISABLE_ALL_INTERRUPTS() __disable_irq() + #define portENABLE_ALL_INTERRUPTS() __enable_irq() +#else /* IAR, CW ARM or GNU ARM gcc */ + #define portDISABLE_ALL_INTERRUPTS() __asm volatile("cpsid i") + #define portENABLE_ALL_INTERRUPTS() __asm volatile("cpsie i") +#endif + +/* There are an uneven number of items on the initial stack, so +portALIGNMENT_ASSERT_pxCurrentTCB() will trigger false positive asserts. */ +#define portALIGNMENT_ASSERT_pxCurrentTCB (void) + +#if( configENABLE_TRUSTZONE == 1 ) + /** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + + /** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) +#else + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) + #define portCLEAN_UP_TCB( pxTCB ) +#endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + + /** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() +#else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + + +/*-----------------------------------------------------------*/ +/* Scheduler utilities. */ + +extern void vPortYieldFromISR(void); +#define portYIELD() vPortYieldFromISR() +#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } } +#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimizations. */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) + #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + /* Generic helper function. */ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + __attribute__((always_inline)) static inline unsigned char ucPortCountLeadingZeros(unsigned long ulBitmap) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + #endif + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_KEIL) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( ( uint32_t ) __CLZ( ( uxReadyPriorities ) ) ) ) + #endif + + #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7 */ +/*-----------------------------------------------------------*/ + +#ifdef configASSERT +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) /* ARM M4/M7(F) core */ + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif +#endif + +/*-----------------------------------------------------------*/ +/* 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 +/*-----------------------------------------------------------*/ +/* 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) +/*-----------------------------------------------------------*/ +void vPortStartFirstTask(void); + /* starts the first task, called from xPortStartScheduler() */ + +void vPortYieldHandler(void); + /* handler for the SWI interrupt */ + +#if configENABLE_FPU /* has floating point unit */ + void vPortEnableVFP(void); + /* enables floating point support in the CPU */ +#endif + +/* Prototypes for interrupt service handlers */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ + void SVC_Handler(void); /* SVC interrupt handler */ + void PendSV_Handler(void); /* PendSV interrupt handler */ + void SysTick_Handler(void); /* Systick interrupt handler */ +#else + void vPortSVCHandler(void); /* SVC interrupt handler */ + void vPortPendSVHandler(void); /* PendSV interrupt handler */ + void vPortTickHandler(void); /* Systick interrupt handler */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC) + #define portINLINE __inline + + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) + #endif + + #if configENABLE_MPU + /* Set the privilege level to user mode if xRunningPrivileged is false. */ + portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) + { + if( xRunningPrivileged != pdTRUE ) + { + __asm volatile ( " mrs r0, control \n" \ + " orr r0, #1 \n" \ + " msr control, r0 \n" \ + :::"r0" ); + } + } + #endif + + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) + { + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortRaiseBASEPRI( void ) + { + uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) + { + uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; + } + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) + { + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); + } + /*-----------------------------------------------------------*/ +#endif + +#if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + BaseType_t configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME(void); /* return pdTRUE if RTOS can enter tickless idle mode, pdFALSE otherwise */ +#endif + +void prvTaskExitError(void); + /* handler to catch task exit errors */ + +#if !configGENERATE_RUN_TIME_STATS_USE_TICKS + extern void FRTOS1_AppConfigureTimerForRuntimeStats(void); + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/projdefs.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/projdefs.h new file mode 100644 index 0000000..762e5c7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/projdefs.h @@ -0,0 +1,125 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.c new file mode 100644 index 0000000..3caadde --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.c @@ -0,0 +1,2947 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( int8_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +Queue_t structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +structure instead holds a pointer to the mutex holder (if any). Map alternative +names to the pcHead and structure member to ensure the readability of the code +is maintained. The QueuePointers_t and SemaphoreData_t types are used to form +a union as their usage is mutually exclusive dependent on what the queue is +being used for. */ +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +typedef struct QueuePointers +{ + int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ +} QueuePointers_t; + +typedef struct SemaphoreData +{ + TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ +} SemaphoreData_t; + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. See the following link for the + * rationale: https://www.freertos.org/Embedded-RTOS-Queues.html + */ +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ + int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union + { + QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ + } u; + + List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ + UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t +name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char *pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + + /* The old xQueueRegistryItem name is maintained above then typedefed to the + new xQueueRegistryItem name below to enable the use of older kernel aware + debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + + /* The queue registry is simply an array of QueueRegistryItem_t structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + +#if( configUSE_MUTEXES == 1 ) + /* + * If a task waiting for a mutex causes the mutex holder to inherit a + * priority, but the waiting task times out, then the holder should + * disinherit the priority - but only down to the highest priority of any + * other tasks that are waiting for the same mutex. This function returns + * that priority. + */ + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; +#endif +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->cRxLock = queueUNLOCKED; + pxQueue->cTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + /* The StaticQueue_t structure and the queue storage area must be + supplied. */ + configASSERT( pxStaticQueue != NULL ); + + /* A queue storage area should be provided if the item size is not 0, and + should not be provided if the item size is 0. */ + configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); + configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticQueue_t or StaticSemaphore_t equals the size of + the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + configASSERT( xSize == sizeof( Queue_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + The address of a statically allocated storage area was also passed in + but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewQueue != NULL ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + note this queue was allocated statically in case the queue is + later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + size_t xQueueSizeInBytes; + uint8_t *pucQueueStorage; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* There is not going to be a queue storage area. */ + xQueueSizeInBytes = ( size_t ) 0; + } + else + { + /* Allocate enough space to hold the maximum number of items that + can be in the queue at any time. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + + /* Allocate the queue and storage area. Justification for MISRA + deviation as follows: pvPortMalloc() always ensures returned memory + blocks are aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the Queue_t structure - which in this case + is an int8_t *. Therefore, whenever the stack alignment requirements + are greater than or equal to the pointer to char requirements the cast + is safe. In other cases alignment requirements are not strict (one or + two bytes). */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + storage area. */ + pucQueueStorage = ( uint8_t * ) pxNewQueue; + pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + note this task was created dynamically in case it is later + deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) +{ + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* No RAM was allocated for the queue storage area, but PC head cannot + be set to NULL because NULL is used as a key to say the queue is used as + a mutex. Therefore just set pcHead to point to the queue as a benign + value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; + } + else + { + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; + } + + /* Initialise the queue members as described where the queue type is + defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static void prvInitialiseMutex( Queue_t *pxNewQueue ) + { + if( pxNewQueue != NULL ) + { + /* The queue create function will set all the queue structure members + correctly for a generic queue, but this function is creating a + mutex. Overwrite those members that need to be set differently - + in particular the information required for priority inheritance. */ + pxNewQueue->u.xSemaphore.xMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* In case this is a recursive mutex. */ + pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0; + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + xNewQueue = xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + xNewQueue = xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + + configASSERT( xSemaphore ); + + /* Mutexes cannot be used in interrupt service routines, so the mutex + holder should not change in an ISR, and therefore a critical section is + not required here. */ + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then xMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--; + + /* Has the recursive call count unwound to 0? */ + if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait ); + + /* pdPASS will only be returned if the mutex was successfully + obtained. The calling task may have entered the Blocked state + before reaching here. */ + if( xReturn != pdFAIL ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) +{ +BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be the + highest priority task wanting to access the queue. If the head item + in the queue is to be overwritten then it does not matter if the + queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; + + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) + { + /* Do not notify the queue set as an existing item + was overwritten in the queue so the number of items + in the queue has not changed. */ + mtCOVERAGE_TEST_MARKER(); + } + else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes + and the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + in the queue. Also don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a + semaphore or mutex. That means prvCopyDataToQueue() cannot result + in a task disinheriting a priority and prvCopyDataToQueue() can be + called here even though the disinherit function does not check if + the scheduler is suspended before accessing the ready lists. */ + ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + /* Similar to xQueueGenericSendFromISR() but used with semaphores where the + item size is 0. Don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + + configASSERT( pxQueue ); + + /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() + if the item size is not 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Normally a mutex would not be given from an interrupt, especially if + there is a mutex holder, as priority inheritance makes no sense for an + interrupts, only tasks. */ + configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* When the queue is used to implement a semaphore no data is ever + moved through the queue but it is still valid to see if the queue 'has + space'. */ + if( uxMessagesWaiting < pxQueue->uxLength ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* A task can only have an inherited priority if it is a mutex + holder - and if there is a mutex holder then the mutex cannot be + given from an ISR. As this is the ISR version of the function it + can be assumed there is no mutex holder and no need to determine if + priority disinheritance is needed. Simply increase the count of + messages (semaphores) available. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The semaphore is a member of a queue set, and + posting to the queue set caused a higher priority + task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data available, remove one item. */ + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_RECEIVE( pxQueue ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* There is now space in the queue, were any tasks waiting to + post to the queue? If so, unblock the highest priority waiting + task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* The timeout has not expired. If the queue is still empty place + the task on the list of tasks waiting to receive from the queue. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The queue contains data again. Loop back to try and read the + data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. If there is no data in the queue exit, otherwise loop + back and attempt to read the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + +#if( configUSE_MUTEXES == 1 ) + BaseType_t xInheritanceOccurred = pdFALSE; +#endif + + /* Check the queue pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* Check this really is a semaphore, in which case the item size will be + 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Semaphores are queues with an item size of 0, and where the + number of messages in the queue is the semaphore's count value. */ + const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxSemaphoreCount > ( UBaseType_t ) 0 ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Semaphores are queues with a data size of zero and where the + messages waiting is the semaphore's count. Reduce the count. */ + pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1; + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + /* Check to see if other tasks are blocked waiting to give the + semaphore, and if so, unblock the highest priority such task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* For inheritance to have occurred there must have been an + initial timeout, and an adjusted timeout cannot become 0, as + if it were 0 the function would have exited. */ + #if( configUSE_MUTEXES == 1 ) + { + configASSERT( xInheritanceOccurred == pdFALSE ); + } + #endif /* configUSE_MUTEXES */ + + /* The semaphore count was 0 and no block time is specified + (or the block time has expired) so exit now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The semaphore count was 0 and a block time was specified + so configure the timeout structure ready to block. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can give to and take from the semaphore + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* A block time is specified and not expired. If the semaphore + count is 0 then enter the Blocked state to wait for a semaphore to + become available. As semaphores are implemented with queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There was no timeout and the semaphore count was not 0, so + attempt to take the semaphore again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* If the semaphore count is 0 exit now as the timeout has + expired. Otherwise return to attempt to take the semaphore that is + known to be available. As semaphores are implemented by queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + #if ( configUSE_MUTEXES == 1 ) + { + /* xInheritanceOccurred could only have be set if + pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to + test the mutex type again to check it is actually a mutex. */ + if( xInheritanceOccurred != pdFALSE ) + { + taskENTER_CRITICAL(); + { + UBaseType_t uxHighestWaitingPriority; + + /* This task blocking on the mutex caused another + task to inherit this task's priority. Now this task + has timed out the priority should be disinherited + again, but only as low as the next highest priority + task that is waiting for the same mutex. */ + uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); + vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); + } + taskEXIT_CRITICAL(); + } + } + #endif /* configUSE_MUTEXES */ + + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position so it can be reset after the data + is read from the queue as this function is only peeking the + data, not removing it. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read pointer. */ + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure ready to enter the blocked + state. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* Timeout has not expired yet, check to see if there is data in the + queue now, and if not enter the Blocked state to wait for data. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There is data in the queue now, so don't enter the blocked + state, instead return to try and obtain the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. If there is still no data in the queue + exit, otherwise go back and try to read the data again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Cannot block in an ISR, so check there is data available. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + const int8_t cRxLock = pxQueue->cRxLock; + + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( cRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + traceQUEUE_DELETE( pxQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + again. */ + vPortFree( pxQueue ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else + { + /* The queue must have been statically allocated, so is not going to be + deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) + { + UBaseType_t uxHighestPriorityOfWaitingTasks; + + /* If a task waiting for a mutex causes the mutex holder to inherit a + priority, but the waiting task times out, then the holder should + disinherit the priority - but only down to the highest priority of any + other tasks that are waiting for the same mutex. For this purpose, + return the priority of the highest priority task that is waiting for the + mutex. */ + if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0U ) + { + uxHighestPriorityOfWaitingTasks = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) ); + } + else + { + uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY; + } + + return uxHighestPriorityOfWaitingTasks; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) +{ +BaseType_t xReturn = pdFALSE; +UBaseType_t uxMessagesWaiting; + + /* This function is called from a critical section. */ + + uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder ); + pxQueue->u.xSemaphore.xMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */ + pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --uxMessagesWaiting; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + int8_t cTxLock = pxQueue->cTxLock; + + /* See if data was added to the queue while it was locked. */ + while( cTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get + added to the pending ready list as the scheduler is still + suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that + a context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --cTxLock; + } + + pxQueue->cTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + int8_t cRxLock = pxQueue->cRxLock; + + while( cRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --cRxLock; + } + else + { + break; + } + } + + pxQueue->cRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char *pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + const char *pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + /* Note there is nothing here to protect against another task adding or + removing entries from the registry while it is being searched. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + pcReturn = xQueueRegistry[ ux ].pcQueueName; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return pcReturn; + } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + + /* Set the handle to NULL to ensure the same queue handle cannot + appear in the registry twice if it is added, removed, then + added again. */ + xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + Queue_t * const pxQueue = xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + const int8_t cTxLock = pxQueueSetContainer->cTxLock; + + traceQUEUE_SEND( pxQueueSetContainer ); + + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + + if( cTxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxQueueSetContainer->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + +/*-----------------------------------------------------------*/ +void vQueueEndScheduler(void) { /* << EST */ +#if configQUEUE_REGISTRY_SIZE>0 + memset(xQueueRegistry, 0, sizeof(xQueueRegistry)); +#endif /* configQUEUE_REGISTRY_SIZE */ +} + + + + + + + + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.h new file mode 100644 index 0000000..dc48ef7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/queue.h @@ -0,0 +1,1657 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void * const pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +void vQueueEndScheduler(void); /* << EST */ + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/readme_gdbBacktraceDebug.txt b/Projects/tinyK22_OpenPnP_Master/Generated_Code/readme_gdbBacktraceDebug.txt new file mode 100644 index 0000000..b4e0d4f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/readme_gdbBacktraceDebug.txt @@ -0,0 +1,31 @@ +readme.txt +---------- +Tasks backtrace switcher/viewer snippet is from the following FreeRTOS Interactive site: +http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + +It generates the following files: +- readme_gdbBacktraceDebug.txt (this file) +- .gdbinit-FreeRTOS-helpers (GDB script file) + +Usage: +- execute GDB script (either manually or in the launch configuration): + source .//Generated_Code//.gdbinit-FreeRTOS-helpers +- execute + freertos_show_threads + to show threads with handlers +- use + freertos_switch_to_task + to show task stack +- use + freertos_restore_running_context + to restore the context before running + +Credits to: +- Artem Pisarneko for his initial contribution +- Prasana for the PendSVHandler updates +- Geoffrey Wossum for the Cortex-M4 contribution + +Link to article: +http://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/semphr.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/semphr.h new file mode 100644 index 0000000..c901d9e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/semphr.h @@ -0,0 +1,1141 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, but instead buried in a more complex
+            // call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = vSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + +/** + * semphr.h + *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/stack_macros.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stack_macros.h new file mode 100644 index 0000000..d6e4730 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stack_macros.h @@ -0,0 +1,130 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );/* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.c new file mode 100644 index 0000000..d913af3 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.c @@ -0,0 +1,1271 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#if 1 /* << EST: handle HIWARE compiler and C++ mode, where UINT32_MAX does not exist */ +#ifndef __HIWARE__ /* C89 compiler does not know stdint.h */ + #include +#endif +#ifndef UINT32_MAX + #define UINT32_MAX 0xffffffff +#endif +#endif /* << EST */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +#if( configUSE_TASK_NOTIFICATIONS != 1 ) + #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c +#endif + +/* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* If the user has not provided application specific Rx notification macros, +or #defined the notification macros away, them provide default implementations +that uses task notifications. */ +/*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */ +#ifndef sbRECEIVE_COMPLETED + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbRECEIVE_COMPLETED */ + +#ifndef sbRECEIVE_COMPLETED_FROM_ISR + #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbRECEIVE_COMPLETED_FROM_ISR */ + +/* If the user has not provided an application specific Tx notification macro, +or #defined the notification macro away, them provide a default implementation +that uses task notifications. */ +#ifndef sbSEND_COMPLETED + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbSEND_COMPLETED */ + +#ifndef sbSEND_COMPLETE_FROM_ISR + #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbSEND_COMPLETE_FROM_ISR */ +/*lint -restore (9026) */ + +/* The number of bytes used to hold the length of a message in the buffer. */ +#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + +/* Bits stored in the ucFlags field of the stream buffer. */ +#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ +#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + +/*-----------------------------------------------------------*/ + +/* Structure that hold state information on the buffer. */ +typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ +{ + volatile size_t xTail; /* Index to the next item to read within the buffer. */ + volatile size_t xHead; /* Index to the next item to write within the buffer. */ + size_t xLength; /* The length of the buffer pointed to by pucBuffer. */ + size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */ + volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */ + volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */ + uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */ + uint8_t ucFlags; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ + #endif +} StreamBuffer_t; + +/* + * The number of bytes available to be read from the buffer. + */ +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION; + +/* + * Add xCount bytes from pucData into the pxStreamBuffer message buffer. + * Returns the number of bytes written, which will either equal xCount in the + * success case, or 0 if there was not enough space in the buffer (in which case + * no data is written into the buffer). + */ +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then reads an entire + * message out of the buffer. If the stream buffer is being used as a stream + * buffer then read as many bytes as possible from the buffer. + * prvReadBytesFromBuffer() is called to actually extract the bytes from the + * buffer's data storage area. + */ +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then writes an entire + * message to the buffer. If the stream buffer is being used as a stream + * buffer then write as many bytes as possible to the buffer. + * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's + * data storage area. + */ +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) PRIVILEGED_FUNCTION; + +/* + * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them + * to pucData. + */ +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, + uint8_t *pucData, + size_t xMaxCount, + size_t xBytesAvailable ) PRIVILEGED_FUNCTION; + +/* + * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to + * initialise the members of the newly created stream buffer structure. + */ +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) + { + uint8_t *pucAllocatedMemory; + uint8_t ucFlags; + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + if( xIsMessageBuffer == pdTRUE ) + { + /* Is a message buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* Not a message buffer and not statically allocated. */ + ucFlags = 0; + configASSERT( xBufferSizeBytes > 0 ); + } + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + /* A stream buffer requires a StreamBuffer_t structure and a buffer. + Both are allocated in a single call to pvPortMalloc(). The + StreamBuffer_t structure is placed at the start of the allocated memory + and the buffer follows immediately after. The requested size is + incremented so the free space is returned as the user would expect - + this is a quirk of the implementation that means otherwise the free + space would be reported as one byte smaller than would be logically + expected. */ + xBufferSizeBytes++; + pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ + + if( pucAllocatedMemory != NULL ) + { + prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */ + pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */ + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer ); + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + } + + return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */ + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) + { + StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */ + StreamBufferHandle_t xReturn; + uint8_t ucFlags; + + configASSERT( pucStreamBufferStorageArea ); + configASSERT( pxStaticStreamBuffer ); + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + if( xIsMessageBuffer != pdFALSE ) + { + /* Statically allocated message buffer. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + } + else + { + /* Statically allocated stream buffer. */ + ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED; + } + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticStreamBuffer_t equals the size of the real + message buffer structure. */ + volatile size_t xSize = sizeof( StaticStreamBuffer_t ); + configASSERT( xSize == sizeof( StreamBuffer_t ) ); + } /*lint !e529 xSize is referenced is configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pucStreamBufferStorageArea, + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + /* Remember this was statically allocated in case it is ever deleted + again. */ + pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; + + traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); + + xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */ + } + else + { + xReturn = NULL; + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + } + + return xReturn; + } + +#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + traceSTREAM_BUFFER_DELETE( xStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both the structure and the buffer were allocated using a single call + to pvPortMalloc(), hence only one call to vPortFree() is required. */ + vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */ + } + #else + { + /* Should not be possible to get here, ucFlags must be corrupt. + Force an assert. */ + configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 ); + } + #endif + } + else + { + /* The structure and buffer were not allocated dynamically and cannot be + freed - just scrub the structure so future use will assert. */ + ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn = pdFAIL; + +#if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; +#endif + + configASSERT( pxStreamBuffer ); + + #if( configUSE_TRACE_FACILITY == 1 ) + { + /* Store the stream buffer number so it can be restored after the + reset. */ + uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; + } + #endif + + /* Can only reset a message buffer if there are no tasks blocked on it. */ + taskENTER_CRITICAL(); + { + if( pxStreamBuffer->xTaskWaitingToReceive == NULL ) + { + if( pxStreamBuffer->xTaskWaitingToSend == NULL ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags ); + xReturn = pdPASS; + + #if( configUSE_TRACE_FACILITY == 1 ) + { + pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + #endif + + traceSTREAM_BUFFER_RESET( xStreamBuffer ); + } + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; + + configASSERT( pxStreamBuffer ); + + /* It is not valid for the trigger level to be 0. */ + if( xTriggerLevel == ( size_t ) 0 ) + { + xTriggerLevel = ( size_t ) 1; + } + + /* The trigger level is the number of bytes that must be in the stream + buffer before a task that is waiting for data is unblocked. */ + if( xTriggerLevel <= pxStreamBuffer->xLength ) + { + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel; + xReturn = pdPASS; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xSpace; + + configASSERT( pxStreamBuffer ); + + xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail; + xSpace -= pxStreamBuffer->xHead; + xSpace -= ( size_t ) 1; + + if( xSpace >= pxStreamBuffer->xLength ) + { + xSpace -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xSpace; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn; + + configASSERT( pxStreamBuffer ); + + xReturn = prvBytesInBuffer( pxStreamBuffer ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace = 0; +size_t xRequiredSpace = xDataLengthBytes; +TimeOut_t xTimeOut; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + + /* Overflow? */ + configASSERT( xRequiredSpace > xDataLengthBytes ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + vTaskSetTimeOutState( &xTimeOut ); + + do + { + /* Wait until the required number of bytes are free in the message + buffer. */ + taskENTER_CRITICAL(); + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + + if( xSpace < xRequiredSpace ) + { + /* Clear notification state as going to wait for space. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one writer. */ + configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); + pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle(); + } + else + { + taskEXIT_CRITICAL(); + break; + } + } + taskEXIT_CRITICAL(); + + traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToSend = NULL; + + } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xSpace == ( size_t ) 0 ) + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ); + + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace; +size_t xRequiredSpace = xDataLengthBytes; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) +{ + BaseType_t xShouldWrite; + size_t xReturn; + + if( xSpace == ( size_t ) 0 ) + { + /* Doesn't matter if this is a stream buffer or a message buffer, there + is no space to write. */ + xShouldWrite = pdFALSE; + } + else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 ) + { + /* This is a stream buffer, as opposed to a message buffer, so writing a + stream of bytes rather than discrete messages. Write as many bytes as + possible. */ + xShouldWrite = pdTRUE; + xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); + } + else if( xSpace >= xRequiredSpace ) + { + /* This is a message buffer, as opposed to a stream buffer, and there + is enough space to write both the message length and the message itself + into the buffer. Start by writing the length of the data, the data + itself will be written later in this function. */ + xShouldWrite = pdTRUE; + ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* There is space available, but not enough space. */ + xShouldWrite = pdFALSE; + } + + if( xShouldWrite != pdFALSE ) + { + /* Writes the data itself. */ + xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */ + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + /* Checking if there is data and clearing the notification state must be + performed atomically. */ + taskENTER_CRITICAL(); + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* If this function was invoked by a message buffer read then + xBytesToStoreMessageLength holds the number of bytes used to hold + the length of the next discrete message. If this function was + invoked by a stream buffer read then xBytesToStoreMessageLength will + be 0. */ + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Clear notification state as going to wait for data. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one reader. */ + configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); + pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Wait for data to be available. */ + traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToReceive = NULL; + + /* Recheck the data available after blocking. */ + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ); + sbRECEIVE_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ); + mtCOVERAGE_TEST_MARKER(); + } + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xBytesAvailable, xOriginalTail; +configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn; + + configASSERT( pxStreamBuffer ); + + /* Ensure the stream buffer is being used as a message buffer. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH ) + { + /* The number of bytes available is greater than the number of bytes + required to hold the length of the next message, so another message + is available. Return its length without removing the length bytes + from the buffer. A copy of the tail is stored so the buffer can be + returned to its prior state as the message is not actually being + removed from the buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable ); + xReturn = ( size_t ) xTempReturn; + pxStreamBuffer->xTail = xOriginalTail; + } + else + { + /* The minimum amount of bytes in a message buffer is + ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is + less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid + value is 0. */ + configASSERT( xBytesAvailable == 0 ); + xReturn = 0; + } + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ); + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) +{ +size_t xOriginalTail, xReceivedLength, xNextMessageLength; +configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength; + + if( xBytesToStoreMessageLength != ( size_t ) 0 ) + { + /* A discrete message is being received. First receive the length + of the message. A copy of the tail is stored so the buffer can be + returned to its prior state if the length of the message is too + large for the provided buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable ); + xNextMessageLength = ( size_t ) xTempNextMessageLength; + + /* Reduce the number of bytes available by the number of bytes just + read out. */ + xBytesAvailable -= xBytesToStoreMessageLength; + + /* Check there is enough space in the buffer provided by the + user. */ + if( xNextMessageLength > xBufferLengthBytes ) + { + /* The user has provided insufficient space to read the message + so return the buffer to its previous state (so the length of + the message is in the buffer again). */ + pxStreamBuffer->xTail = xOriginalTail; + xNextMessageLength = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* A stream of bytes is being received (as opposed to a discrete + message), so read as many bytes as possible. */ + xNextMessageLength = xBufferLengthBytes; + } + + /* Read the actual data. */ + xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */ + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +size_t xTail; + + configASSERT( pxStreamBuffer ); + + /* True if no bytes are available. */ + xTail = pxStreamBuffer->xTail; + if( pxStreamBuffer->xHead == xTail ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) +{ +BaseType_t xReturn; +size_t xBytesToStoreMessageLength; +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + /* This generic version of the receive function is used by both message + buffers, which store discrete messages, and stream buffers, which store a + continuous stream of bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + /* True if the available space equals zero. */ + if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) +{ +size_t xNextHead, xFirstLength; + + configASSERT( xCount > ( size_t ) 0 ); + + xNextHead = pxStreamBuffer->xHead; + + /* Calculate the number of bytes that can be added in the first write - + which may be less than the total number of bytes that need to be added if + the buffer will wrap back to the beginning. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount ); + + /* Write as many bytes as can be written in the first write. */ + configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the number of bytes written was less than the number that could be + written in the first write... */ + if( xCount > xFirstLength ) + { + /* ...then write the remaining bytes to the start of the buffer. */ + configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xNextHead += xCount; + if( xNextHead >= pxStreamBuffer->xLength ) + { + xNextHead -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxStreamBuffer->xHead = xNextHead; + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable ) +{ +size_t xCount, xFirstLength, xNextTail; + + /* Use the minimum of the wanted bytes and the available bytes. */ + xCount = configMIN( xBytesAvailable, xMaxCount ); + + if( xCount > ( size_t ) 0 ) + { + xNextTail = pxStreamBuffer->xTail; + + /* Calculate the number of bytes that can be read - which may be + less than the number wanted if the data wraps around to the start of + the buffer. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount ); + + /* Obtain the number of bytes it is possible to obtain in the first + read. Asserts check bounds of read and write. */ + configASSERT( xFirstLength <= xMaxCount ); + configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the total number of wanted bytes is greater than the number + that could be read in the first read... */ + if( xCount > xFirstLength ) + { + /*...then read the remaining bytes from the start of the buffer. */ + configASSERT( xCount <= xMaxCount ); + ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Move the tail pointer to effectively remove the data read from + the buffer. */ + xNextTail += xCount; + + if( xNextTail >= pxStreamBuffer->xLength ) + { + xNextTail -= pxStreamBuffer->xLength; + } + + pxStreamBuffer->xTail = xNextTail; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) +{ +/* Returns the distance between xTail and xHead. */ +size_t xCount; + + xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; + xCount -= pxStreamBuffer->xTail; + if ( xCount >= pxStreamBuffer->xLength ) + { + xCount -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) +{ + /* Assert here is deliberately writing to the entire buffer to ensure it can + be written to without generating exceptions, and is setting the buffer to a + known value to assist in development/debugging. */ + #if( configASSERT_DEFINED == 1 ) + { + /* The value written just has to be identifiable when looking at the + memory. Don't use 0xA5 as that is the stack fill value and could + result in confusion as to what is actually being observed. */ + const BaseType_t xWriteValue = 0x55; + configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); + } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ + #endif + + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ + pxStreamBuffer->pucBuffer = pucBuffer; + pxStreamBuffer->xLength = xBufferSizeBytes; + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; + pxStreamBuffer->ucFlags = ucFlags; +} + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) + { + return xStreamBuffer->uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) + { + xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) + { + return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ); + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.h new file mode 100644 index 0000000..7ed8612 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/stream_buffer.h @@ -0,0 +1,856 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t * StreamBufferHandle_t; + + +/** + * message_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
+
+ * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
+
+    // Create a stream buffer that can hold 100 bytes.  The memory used to hold
+    // both the stream buffer structure and the data in the stream buffer is
+    // allocated dynamically.
+    xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
+
+    if( xStreamBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // stream buffer.
+    }
+    else
+    {
+        // The stream buffer was created successfully and can now be used.
+    }
+}
+
+ * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) + +/** + * stream_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
+                                                size_t xTriggerLevelBytes,
+                                                uint8_t *pucStreamBufferStorageArea,
+                                                StaticStreamBuffer_t *pxStaticStreamBuffer );
+
+ * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the streams.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the streams within the stream
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the stream buffer structure.
+StaticStreamBuffer_t xStreamBufferStruct;
+
+void MyFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xTriggerLevel = 1;
+
+    xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
+                                               xTriggerLevel,
+                                               ucBufferStorage,
+                                               &xStreamBufferStruct );
+
+    // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
+    // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
+    // reference the created stream buffer in other stream buffer API calls.
+
+    // Other code that uses the stream buffer can go here.
+}
+
+
+ * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+                          const void *pvTxData,
+                          size_t xDataLengthBytes,
+                          TickType_t xTicksToWait );
+
+ * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: +
+void vAFunction( StreamBufferHandle_t xStreamBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the stream buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the stream buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xStreamBufferSend() times out before there was enough
+        // space in the buffer for the data to be written, but it did
+        // successfully write xBytesSent bytes.
+    }
+
+    // Send the string to the stream buffer.  Return immediately if there is not
+    // enough space in the buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The entire string could not be added to the stream buffer because
+        // there was not enough free space in the buffer, but xBytesSent bytes
+        // were sent.  Could try again to send the remaining bytes.
+    }
+}
+
+ * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+                                 const void *pvTxData,
+                                 size_t xDataLengthBytes,
+                                 BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBufferHandle_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the stream buffer.
+    xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
+                                           ( void * ) pcStringToSend,
+                                           strlen( pcStringToSend ),
+                                           &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // There was not enough free space in the stream buffer for the entire
+        // string to be written, ut xBytesSent bytes were written.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+                             void *pvRxData,
+                             size_t xBufferLengthBytes,
+                             TickType_t xTicksToWait );
+
+ * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: +
+void vAFunction( StreamBuffer_t xStreamBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
+    // Wait in the Blocked state (so not using any CPU processing time) for a
+    // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
+    // available.
+    xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
+                                           ( void * ) ucRxData,
+                                           sizeof( ucRxData ),
+                                           xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains another xRecievedBytes bytes of data, which can
+        // be processed here....
+    }
+}
+
+ * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+                                    void *pvRxData,
+                                    size_t xBufferLengthBytes,
+                                    BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBuffer_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next stream from the stream buffer.
+    xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // ucRxData contains xReceivedBytes read from the stream buffer.
+        // Process the stream here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
+
+ * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; + +StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#endif + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( STREAM_BUFFER_H ) */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/task.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/task.h new file mode 100644 index 0000000..85a5b07 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/task.h @@ -0,0 +1,2452 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V10.2.1" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 2 +#define tskKERNEL_VERSION_BUILD 1 + +/* MPU region parameters passed in ulParameters + * of MemoryRegion_t struct. */ +#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) +#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock* TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + configSTACK_DEPTH_TYPE usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; + #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t * const pxTaskBuffer; + #endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  configSTACK_DEPTH_TYPE usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and a handle to the created task is returned. If either + * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and + * NULL is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+// The StaticTask_t variable is only included in the structure when
+// configSUPPORT_STATIC_ALLOCATION is set to 1.  The PRIVILEGED_DATA macro can
+// be used to force the variable into the RTOS kernel's privileged data area.
+static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+
+	&xTaskBuffer; // Holds the task's data structure.
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
+ * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+    // Obtain the handle of a task from its name.
+    xHandle = xTaskGetHandle( "Task_Name" );
+
+    // Check the handle is not NULL.
+    configASSERT( xHandle );
+
+    // Use the handle to obtain further information about the task.
+    vTaskGetInfo( xHandle,
+                  &xTaskDetails,
+                  pdTRUE, // Include the high water mark in xTaskDetails.
+                  eInvalid ); // Include the task state in xTaskDetails.
+ }
+   
+ * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Do not + * call from an interrupt service routine - call + * xTaskGetApplicationTaskTagFromISR() instead. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Can + * be called from an interrupt service routine. + */ + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + + /* Each task contains an array of pointers that is dimensioned by the + configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + kernel does not use the pointers itself, so the application writer can use + the pointers for any purpose they wish. The following two functions are + used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) // < 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer, size_t bufSize);
//<< EST + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer, size_t bufSize) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** +* task. h +*
TickType_t xTaskGetIdleRunTimeCounter( void );
+* +* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS +* must both be defined as 1 for this function to be available. The application +* must also then provide definitions for +* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() +* to configure a peripheral timer/counter and return the timers current count +* value respectively. The counter should be at least 10 times the frequency of +* the tick count. +* +* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total +* accumulated execution time being stored for each task. The resolution +* of the accumulated time value depends on the frequency of the timer +* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. +* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total +* execution time of each task into a buffer, xTaskGetIdleRunTimeCounter() +* returns the total execution time of just the idle task. +* +* @return The total run time of the idle task. This is the amount of time the +* idle task has actually been executing. The unit of time is dependent on the +* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +* portGET_RUN_TIME_COUNTER_VALUE() macros. +* +* \defgroup xTaskGetIdleRunTimeCounter xTaskGetIdleRunTimeCounter +* \ingroup TaskUtils +*/ +TickType_t xTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object.  Examples of such
+ * objects are queues, semaphores, mutexes and event groups.  Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value.  In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified.  The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task.  If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited.  How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * 
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +#ifdef __GNUC__ /* << EST: 'used' attribute need for LTO (Link Time Optimization) */ + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION __attribute__((used)); +#else + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; +#endif + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critial + * section. + */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + +#if 1 /* << EST */ +/*! + \brief Collects all the task handles present in the system and stores them in to an array of task handles. + \param pxTaskHandleArray Pointer to an array of task handles where the handles will be stored. + \param xNofTaskHandlesInArray Number of task handles in the array. + \return Number of task handles stored in array. + */ +UBaseType_t xGetTaskHandles(TaskHandle_t pxTaskHandleArray[], UBaseType_t xNofTaskHandlesInArray); + +/*! + * \brief Returns stack information about the given task handle. + * \param xTask Task handle + * \param ppxStart Returns the start of the stack area. This is the 'bottom' of the stack, with the stack pointer growing to the 'top'. + * \param ppxEnd Returns the end of the stack area. This is the 'top' of the stack where the stack pointer grows to. + * \param ppxTopOfStack Returns the current stack pointer value. + * \param pucStaticallyAllocated 0, if statically allocated, !=0 if allocated dynamically + */ +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated); + +/*! + * \brief Return a pointer to the task start + * \param xTask Task handle + */ +uint8_t* pxTaskGetStackStart(TaskHandle_t xTask); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/tasks.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/tasks.c new file mode 100644 index 0000000..d80c87e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/tasks.c @@ -0,0 +1,5474 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "stack_macros.h" + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) +#include "UTIL1.h" /* interface to utility because used for safe string routines */ /* << EST */ +#endif + +#if (configCOMPILER == configCOMPILER_ARM_IAR) /* << EST: suppress warnings for IAR */ +#pragma diag_suppress=pa082 /* Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement */ +#endif +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting +functions but without including stdio.h here. */ +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* Values that can be assigned to the ucNotifyState member of the TCB. */ +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* Bits used to recored how a task's stack and TCB were allocated. */ +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + +/* If any of the following are set then task stacks are filled with a known +value so the high water mark can be determined. If none of the following are +set then don't fill the stack so there is no unnecessary dependency on memset. */ +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 +#else + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 +#endif + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskRUNNING_CHAR ( 'X' ) +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/* + * Some kernel aware debuggers require the data the debugger needs access to be + * global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/* The name allocated to the Idle task. This can be overridden by defining +configIDLE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configIDLE_TASK_NAME + #define configIDLE_TASK_NAME "IDLE" +#endif + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + List_t *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +/*-----------------------------------------------------------*/ + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ +/* + * Place the task represented by pxTCB which has been in a ready list before + * into the appropriate ready list for the task. + * It is inserted at the end of the list. + */ +#define prvReAddTaskToReadyList( pxTCB ) \ + traceREADDED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ) + +#endif /* configUSE_SEGGER_SYSTEM_VIEWER_HOOKS */ /* << EST */ + +/* + * Several functions take an TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority +of the task to which it belongs (coded to allow it to be held in reverse +priority order). However, it is occasionally borrowed for other purposes. It +is important its value is not updated due to a task priority change while it is +being used for another purpose. The following bit definition is used to inform +the scheduler that the value should not be changed - in which case it is the +responsibility of whichever module is using the value to ensure it gets set back +to its original value when it is released. */ +#if( configUSE_16_BIT_TICKS == 1 ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#else + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t *pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue; + volatile uint8_t ucNotifyState; + #endif + + /* See the comments in FreeRTOS.h with the definition of + tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif + +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name +below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ +PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. -------------------- +xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but +doing so breaks some kernel aware debuggers and debuggers that rely on removing +the static qualifier. */ +#if configLTO_HELPER + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#else + PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#endif + +#if( INCLUDE_vTaskDelete == 1 ) + +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#else + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#endif + PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#else + PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#endif +#endif + +/* Global POSIX errno. Its value is changed upon context switching to match +the errno of the currently running task. */ +#if ( configUSE_POSIX_ERRNO == 1 ) + int FreeRTOS_errno = 0; +#endif + +/* Other file private variables. --------------------------------*/ +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#endif +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA /*static*/ volatile BaseType_t xSchedulerRunning = pdFALSE; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +#endif +PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +/* Context switches are held pending while the scheduler is suspended. Also, +interrupts must not manipulate the xStateListItem of a TCB, or any of the +lists the xStateListItem can be referenced from, if the scheduler is suspended. +If an interrupt needs to unblock a task while the scheduler is suspended then it +moves the task's event list item into the xPendingReadyList, ready for the +kernel to move the task from the pending ready list into the real ready list +when the scheduler is unsuspended. The pending ready list itself can only be +accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + /* Do not move these variables to function scope as doing so prevents the + code working with debuggers that need to remove the static qualifier. */ + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ +#if 1 /* << EST: prevent optimizations and removal of the following variable with -O1, -O2 or -O3, as used by NXP TAD */ + PRIVILEGED_DATA static + #ifdef __GNUC__ + __attribute__((used)) + #endif + uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#else + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#endif + +#endif + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +/* Callback function prototypes. --------------------------*/ +#if( configCHECK_FOR_STACK_OVERFLOW > 0 ) +#if 1 /* << EST */ + extern void configCHECK_FOR_STACK_OVERFLOW_NAME( TaskHandle_t xTask, char *pcTaskName ); +#else + extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); +#endif +#endif + +#if( configUSE_TICK_HOOK > 0 ) + + extern void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +/* File private functions. --------------------------------*/ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* INCLUDE_vTaskSuspend */ + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Searches pxList for a task with name pcNameToQuery - returning a handle to + * the task if it is found, or NULL if the task is not found. + */ +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ); + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + /* + * Helper function used to pad task names with spaces when printing out + * human readable tables of task information. + */ +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) PRIVILEGED_FUNCTION; +#endif + +#endif +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; + +/* + * freertos_tasks_c_additions_init() should only be called if the user definable + * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro + * called by the function. + */ +#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + + static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION; + +#endif + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) + { + TCB_t *pxNewTCB; + TaskHandle_t xReturn; + + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTask_t equals the size of the real task + structure. */ + volatile size_t xSize = sizeof( StaticTask_t ); + configASSERT( xSize == sizeof( TCB_t ) ); + ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */ + } + #endif /* configASSERT_DEFINED */ + + + if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) + { + /* The memory used for the task's TCB and stack are passed into this + function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer != NULL ); + configASSERT( pxTaskDefinition->pxTaskBuffer != NULL ); + + if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note + this task had a statically allocated stack in case it is + later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t *pxStack; + + /* Allocate space for the stack used by the task being created. */ + pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) +{ +StackType_t *pxTopOfStack; +UBaseType_t x; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ + + /* Calculate the top of stack address. This depends on whether the stack + grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as required + by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + #if( configRECORD_STACK_HIGH_ADDRESS == 1 ) + { + /* Also record the stack's high address, which may assist + debugging. */ + pxNewTCB->pxEndOfStack = pxTopOfStack; + } + #endif /* configRECORD_STACK_HIGH_ADDRESS */ + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + if( pcName != NULL ) + { + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + } + else + { + /* The task has not been given a name, so just ensure there is a NULL + terminator when it is read out. */ + pxNewTCB->pcTaskName[ 0 ] = 0x00; + } + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + pxNewTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxNewTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxNewTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxNewTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; + } + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + { + for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) + { + pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + } + } + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + pxNewTCB->ulNotifiedValue = 0; + pxNewTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + } + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + pxNewTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #else /* portUSING_MPU_WRAPPERS */ + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) +{ + /* Ensure interrupts don't access the task lists while the lists are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Increment the uxTaskNumber also so kernel aware debuggers can + detect that the task lists need re-generating. This is done before + portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will + not return. */ + uxTaskNumber++; + + if( pxTCB == pxCurrentTCB ) + { + /* A task is deleting itself. This cannot complete within the + task itself, as a context switch to another task is required. + Place the task in the termination list. The idle task will + check the termination list and free up any memory allocated by + the scheduler for the TCB and stack of the deleted task. */ + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxDeletedTasksWaitingCleanUp; + + /* The pre-delete hook is primarily for the Windows simulator, + in which Windows specific clean up operations are performed, + after which it is not possible to yield away from this task - + hence xYieldPending is used to latch that a context switch is + required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + } + else + { + --uxCurrentNumberOfTasks; + prvDeleteTCB( pxTCB ); + + /* Reset the next expected unblock time in case it referred to + the task that has just been deleted. */ + prvResetNextTaskUnblockTime(); + } + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if it is the currently running task that has just + been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL( xTimeToWake ); + + /* prvAddCurrentTaskToDelayedList() needs the block time, not + the time to wake, so subtract the current tick count. */ + prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + BaseType_t xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == 0 ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t const * pxStateList, *pxDelayedList, *pxOverflowedDelayedList; + const TCB_t * const pxTCB = xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + pxDelayedList = pxDelayedTaskList; + pxOverflowedDelayedList = pxOverflowDelayedTaskList; + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. Is it genuinely suspended or is it blocked + indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + /* The task does not appear on the event list item of + and of the RTOS objects, but could still be in the + blocked state if it is waiting on its notification + rather than waiting on an object. */ + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + eReturn = eBlocked; + } + else + { + eReturn = eSuspended; + } + } + #else + { + eReturn = eSuspended; + } + #endif + } + else + { + eReturn = eBlocked; + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) + { + /* The task being queried is referenced from the deleted + tasks list, or it is not referenced from any lists at + all. */ + eReturn = eDeleted; + } + #endif + + else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the task + that called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn, uxSavedInterruptState; + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* If null is passed in here then it is the priority of the calling + task that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) + { + TCB_t *pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + nothing more than change its priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before + adding it to it's new ready list. As we are in a critical + section we can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired != pdFALSE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + suspended list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task was blocked to wait for a notification, but is + now suspended, so no notification was received. */ + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + } + #endif + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */ + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = xTask; + + /* Accesses xPendingReadyList so must be called from a critical + section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */ + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* The ready list can be accessed even if the scheduler is + suspended because this is inside a critical section. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* A higher priority task may have just been resumed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + but will leave the lists in the correct state for the + next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Ready lists can be accessed so move the task from the + suspended list to the ready list directly. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + is held in the pending ready list until the scheduler is + unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ +BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxIdleTaskTCBBuffer = NULL; + StackType_t *pxIdleTaskStackBuffer = NULL; + uint32_t ulIdleTaskStackSize; + + /* The Idle task is created using user provided RAM - obtain the + address of the RAM then create the idle task. */ + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, + configIDLE_TASK_NAME, + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + + if( xIdleTaskHandle != NULL ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + #else + { + /* The Idle task is being created using dynamically allocated RAM. */ + xReturn = xTaskCreate( prvIdleTask, + configIDLE_TASK_NAME, + configMINIMAL_STACK_SIZE, + ( void * ) NULL, + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* freertos_tasks_c_additions_init() should only be called if the user + definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is + the only macro called by the function. */ + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + { + freertos_tasks_c_additions_init(); + } + #endif + + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to the task that will run first. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + xNextTaskUnblockTime = portMAX_DELAY; + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS + is set to 0 and the following line fails to build then ensure you do not + have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your + FreeRTOSConfig.h file. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + traceTASK_SWITCHED_IN(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); + } + + /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, + meaning xIdleTaskHandle is not used anywhere else. */ + ( void ) xIdleTaskHandle; +} +/*-----------------------------------------------------------*/ + +#if INCLUDE_vTaskEndScheduler /* << EST */ +#include "queue.h" +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + /* << EST initialize back things for properly ending the scheduler */ + /* set back the scheduler and tasks */ + pxCurrentTCB = NULL; + memset(pxReadyTasksLists, 0, sizeof(pxReadyTasksLists)); + memset(&xDelayedTaskList1, 0, sizeof(xDelayedTaskList1)); + pxDelayedTaskList = NULL; + pxOverflowDelayedTaskList = NULL; + memset(&xPendingReadyList, 0, sizeof(xPendingReadyList)); + + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + uxTopReadyPriority = tskIDLE_PRIORITY; + uxPendedTicks = ( UBaseType_t ) 0U; + xYieldPending = pdFALSE; + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ + xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + + /* reset the queues */ + vQueueEndScheduler(); + /* now do the very low level stuff and reset the heap memory if possible */ + /* << EST end */ + vPortEndScheduler(); +} +#endif /* << EST */ +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + BaseType_t. Please read Richard Barry's reply in the following link to a + post in the FreeRTOS support forum before reporting this as a bug! - + http://goo.gl/wu4acr */ + ++uxSchedulerSuspended; + portMEMORY_BARRIER(); +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + + /* uxHigherPriorityReadyTasks takes care of the case where + configUSE_PREEMPTION is 0, so there may be tasks above the idle priority + task that are in the Ready state, even though the idle task is + running. */ + #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + { + if( uxTopReadyPriority > tskIDLE_PRIORITY ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #else + { + const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; + + /* When port optimised task selection is used the uxTopReadyPriority + variable is used as a bit map. If bits other than the least + significant bit are set then there are tasks that have a priority + above the idle priority that are in the Ready state. This takes + care of the case where the co-operative scheduler is in use. */ + if( uxTopReadyPriority > uxLeastSignificantBit ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #endif + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else if( uxHigherPriorityReadyTasks != pdFALSE ) + { + /* There are tasks in the Ready state that have a priority above the + idle priority. This path can only be reached if + configUSE_PREEMPTION is 0. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ +TCB_t *pxTCB = NULL; +BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If the moved task has a priority higher than the current + task then a yield must be performed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxTCB != NULL ) + { + /* A task was unblocked while the scheduler was suspended, + which may have prevented the next unblock time from being + re-calculated, in which case re-calculate it now. Mainly + important for low power tickless implementations, where + this can prevent an unnecessary exit from low power + state. */ + prvResetNextTaskUnblockTime(); + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does + not slip, and that any delayed tasks are resumed at the correct + time. */ + { + UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */ + + if( uxPendedCounts > ( UBaseType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedCounts; + } while( uxPendedCounts > ( UBaseType_t ) 0U ); + + uxPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xYieldPending != pdFALSE ) + { + #if( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ +TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portTICK_TYPE_ENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portTICK_TYPE_EXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ +TickType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +TCB_t *pxTCB; + + /* If null is passed in here then the name of the calling task is being + queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) + { + TCB_t *pxNextTCB, *pxFirstTCB, *pxReturn = NULL; + UBaseType_t x; + char cNextChar; + BaseType_t xBreakLoop; + + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Check each character in the name looking for a match or + mismatch. */ + xBreakLoop = pdFALSE; + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cNextChar = pxNextTCB->pcTaskName[ x ]; + + if( cNextChar != pcNameToQuery[ x ] ) + { + /* Characters didn't match. */ + xBreakLoop = pdTRUE; + } + else if( cNextChar == ( char ) 0x00 ) + { + /* Both strings terminated, a match must have been + found. */ + pxReturn = pxNextTCB; + xBreakLoop = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xBreakLoop != pdFALSE ) + { + break; + } + } + + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t uxQueue = configMAX_PRIORITIES; + TCB_t* pxTCB; + + /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ + configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); + + vTaskSuspendAll(); + { + /* Search the ready lists. */ + do + { + uxQueue--; + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + + if( pxTCB != NULL ) + { + /* Found the handle. */ + break; + } + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + } + + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the suspended list. */ + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + } + } + #endif + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the deleted list. */ + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + } + } + #endif + } + ( void ) xTaskResumeAll(); + + return pxTCB; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + task in the Blocked state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task in the Suspended state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( const TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) + { + TCB_t *pxTCB = xTask; + BaseType_t xReturn; + + configASSERT( pxTCB ); + + vTaskSuspendAll(); + { + /* A task can only be prematurely removed from the Blocked state if + it is actually in the Blocked state. */ + if( eTaskGetState( xTask ) == eBlocked ) + { + xReturn = pdPASS; + + /* Remove the reference to the task from the blocked list. An + interrupt won't touch the xStateListItem because the + scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove it from + the event list too. Interrupts can touch the event list item, + even though the scheduler is suspended, so a critical section + is used. */ + taskENTER_CRITICAL(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + pxTCB->ucDelayAborted = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Place the unblocked task into the appropriate ready list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only be + performed if the unblocked task has a priority that is + equal to or higher than the currently executing task. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Pend the yield to be performed when the scheduler + is unsuspended. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + xReturn = pdFAIL; + } + } + ( void ) xTaskResumeAll(); + + return xReturn; + } + +#endif /* INCLUDE_xTaskAbortDelay */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskIncrementTick( void ) +{ +TCB_t * pxTCB; +TickType_t xItemValue; +BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; + + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + xTickCount = xConstTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */ + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + the queue in the order of their wake time - meaning once one task + has been found whose block time has not expired there is no need to + look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + to the maximum possible value so it is extremely + unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + break; + } + else + { + /* The delayed list is not empty, get the value of the + item at the head of the delayed list. This is the time + at which the task at the head of the delayed list must + be removed from the Blocked state. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + item value is the time at which the task at the head + of the blocked list must be removed from the Blocked + state - so record the item value in + xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; /*lint !e9011 Code structure here is deedmed easier to understand with multiple breaks. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove + it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + only be performed if the unblocked task has a + priority that is equal to or higher than the + currently executing task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( UBaseType_t ) 0U ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + #endif + } + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + { + TCB_t *xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xTCB->pxTaskTag = pxHookFunction; + } + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = pxTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = pxTCB->pxTaskTag; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + TCB_t *xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#ifdef __GNUC__ /* << EST */ +__attribute__((used)) /* using C++ compiler, vTaskSwitchContext() might be removed even with -O0? */ +#endif +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskCHECK_FOR_STACK_OVERFLOW(); + + /* Before the currently running task is switched out, save its errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + pxCurrentTCB->iTaskErrno = FreeRTOS_errno; + } + #endif + + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + traceTASK_SWITCHED_IN(); + + /* After the new task is switched in, update the global errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = pxCurrentTCB->iTaskErrno; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. The queue that contains the event + list is locked, preventing simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event groups implementation. */ + configASSERT( uxSchedulerSuspended != 0 ); + + /* Store the item value in the event list item. It is safe to access the + event list item here as interrupts won't access the event list item of a + task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + list. It is safe to access the event list here because it is part of an + event group implementation - and interrupts don't access event groups + directly (instead they access them indirectly by pending function calls to + the task level). */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called with the scheduler suspended. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* If the task should block indefinitely then set the block time to a + value that will be recognised as an indefinite delay inside the + prvAddCurrentTaskToDelayedList() function. */ + if( xWaitIndefinitely != pdFALSE ) + { + xTicksToWait = portMAX_DELAY; + } + + traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + be removed as it is known to be the highest priority. Remove the TCB from + the delayed list, and add it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means exclusive access to the event list is guaranteed here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + might be set to the blocked task's time out time. If the task is + unblocked for a reason other than a timeout xNextTaskUnblockTime is + normally left unchanged, because it is automatically reset to a new + value when the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter sleep mode + at the earliest possible time - so reset xNextTaskUnblockTime here to + ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +{ +TCB_t *pxUnblockedTCB; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event flags implementation. */ + configASSERT( uxSchedulerSuspended != pdFALSE ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + event flags. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( pxEventListItem ); + + /* Remove the task from the delayed list and add it to the ready list. The + scheduler is suspended so interrupts will not be accessing the ready + lists. */ + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The unblocked task has a priority above that of the calling task, so + a context switch is required. This function is called with the + scheduler suspended so xYieldPending is set so the context switch + occurs immediately that the scheduler is resumed (unsuspended). */ + xYieldPending = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + taskENTER_CRITICAL(); + { + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* For internal use only as it does not use a critical section. */ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) + { + /* The delay was aborted, which is not the same as a time out, + but has the same result. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + xReturn = pdTRUE; + } + else + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + if( *pxTicksToWait == portMAX_DELAY ) + { + /* If INCLUDE_vTaskSuspend is set to 1 and the block time + specified is the maximum block time then the task should block + indefinitely, and therefore never time out. */ + xReturn = pdFALSE; + } + else + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which + vTaskSetTimeout() was called, but has also overflowed since + vTaskSetTimeOut() was called. It must have wrapped all the way + around and gone past again. This passed since vTaskSetTimeout() + was called. */ + xReturn = pdTRUE; + } + else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= xElapsedTime; + vTaskInternalSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + *pxTicksToWait = 0; + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t const *pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) + { + TCB_t * pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE + SCHEDULER IS STARTED. **/ + + /* In case a task that has a secure context deletes itself, in which case + the idle task is responsible for deleting the task's secure context, if + any. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + for( ;; ) + { + /* See if any tasks have deleted themselves - if so then the idle task + is responsible for freeing the deleted task's TCB and stack. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + /* EST: Use user hook name */ + extern void configUSE_IDLE_HOOK_NAME( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + configUSE_IDLE_HOOK_NAME(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + #if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + if (configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME()) /* ask application if it shall enter tickless idle mode */ + #endif + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + /* Define the following macro to set xExpectedIdleTime to 0 + if the application does not want + portSUPPRESS_TICKS_AND_SLEEP() to be called. */ + configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE != 0 ) + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + /* If all the tasks are in the suspended list (which might mean they + have an infinite block time rather than actually being suspended) + then it is safe to turn all clocks off and just wait for external + interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return eReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + } + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void *pvReturn = NULL; + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) + { + TCB_t *pxTCB; + + /* If null is passed in here then we are modifying the MPU settings of + the calling task. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + + /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + TCB_t *pxTCB; + + /* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL() + being called too often in the idle task. */ + while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) + { + taskENTER_CRITICAL(); + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + --uxCurrentNumberOfTasks; + --uxDeletedTasksWaitingCleanUp; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + #endif /* INCLUDE_vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + + void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) + { + TCB_t *pxTCB; + + /* xTask is NULL then get the state of the calling task. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; + pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName [ 0 ] ); + pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; + pxTaskStatus->pxStackBase = pxTCB->pxStack; + pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; + } + #else + { + pxTaskStatus->uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatus->ulRunTimeCounter = 0; + } + #endif + + /* Obtaining the task state is a little fiddly, so is only done if the + value of eState passed into this function is eInvalid - otherwise the + state is just set to whatever is passed in. */ + if( eState != eInvalid ) + { + if( pxTCB == pxCurrentTCB ) + { + pxTaskStatus->eCurrentState = eRunning; + } + else + { + pxTaskStatus->eCurrentState = eState; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a + chance it is actually just blocked indefinitely - so really + it should be reported as being in the Blocked state. */ + if( eState == eSuspended ) + { + vTaskSuspendAll(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatus->eCurrentState = eBlocked; + } + } + ( void ) xTaskResumeAll(); + } + } + #endif /* INCLUDE_vTaskSuspend */ + } + } + else + { + pxTaskStatus->eCurrentState = eTaskGetState( pxTCB ); + } + + /* Obtaining the stack space takes some time, so the xGetFreeStackSpace + parameter is provided to allow it to be skipped. */ + if( xGetFreeStackSpace != pdFALSE ) + { + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); + } + #else + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); + } + #endif + } + else + { + pxTaskStatus->usStackHighWaterMark = 0; + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) + { + configLIST_VOLATILE TCB_t *pxNextTCB, *pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Populate an TaskStatus_t structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of TaskStatus_t in task.h for the + meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + uxTask++; + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( configSTACK_DEPTH_TYPE ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + same except for their return type. Using configSTACK_DEPTH_TYPE allows the + user to determine the return type. It gets around the problem of the value + overflowing on 8-bit types without breaking backward compatibility for + applications that expect an 8-bit return type. */ + configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + configSTACK_DEPTH_TYPE uxReturn; + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are + the same except for their return type. Using configSTACK_DEPTH_TYPE + allows the user to determine the return type. It gets around the + problem of the value overflowing on 8-bit types without breaking + backward compatibility for applications that expect an 8-bit return + type. */ + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up + to the task to free any memory allocated at the application level. */ + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) + { + /* The task can only have been allocated dynamically - free both + the stack and TCB. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* The task could have been allocated statically or dynamically, so + check what was statically allocated before trying to free the + memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) + { + /* Both the stack and TCB were allocated dynamically, so both + must be freed. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ +TCB_t *pxTCB; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set xNextTaskUnblockTime to + the maximum possible value so it is extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + ( pxTCB ) = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxMutexHolderTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. _RB_ Is this still + needed as interrupts can no longer use mutexes? */ + if( pxMutexHolder != NULL ) + { + /* If the holder of the mutex has a priority below the priority of + the task attempting to obtain the mutex then it will temporarily + inherit the priority of the task attempting to obtain the mutex. */ + if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + priority. Only reset the event list item value if the value is + not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need + to be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxMutexHolderTCB ); +#else + prvAddTaskToReadyList( pxMutexHolderTCB ); +#endif + } + else + { + /* Just inherit the priority. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); + + /* Inheritance occurred. */ + xReturn = pdTRUE; + } + else + { + if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) + { + /* The base priority of the mutex holder is lower than the + priority of the task attempting to take the mutex, but the + current priority of the mutex holder is not lower than the + priority of the task attempting to take the mutex. + Therefore the mutex holder must have already inherited a + priority, but inheritance would have occurred if that had + not been the case. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + /* A task can only have an inherited priority if it holds the mutex. + If the mutex is held by a task then it cannot be given from an + interrupt, and if a mutex is given by the holding task then it must + be the running state task. */ + configASSERT( pxTCB == pxCurrentTCB ); + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + /* Has the holder of the mutex inherited the priority of another + task? */ + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* A task can only have an inherited priority if it holds + the mutex. If the mutex is held by a task then it cannot be + given from an interrupt, and if a mutex is given by the + holding task then it must be the running state task. Remove + the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the + new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + any other purpose if this task is running, and it must be + running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + + /* Return true to indicate that a context switch is required. + This is only actually required in the corner case whereby + multiple mutexes were held and the mutexes were given back + in an order different to that in which they were taken. + If a context switch did not occur when the first mutex was + returned, even if a task was waiting on it, then a context + switch should occur when the last mutex is returned whether + a task is waiting on it or not. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) + { + TCB_t * const pxTCB = pxMutexHolder; + UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse; + const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1; + + if( pxMutexHolder != NULL ) + { + /* If pxMutexHolder is not NULL then the holder must hold at least + one mutex. */ + configASSERT( pxTCB->uxMutexesHeld ); + + /* Determine the priority to which the priority of the task that + holds the mutex should be set. This will be the greater of the + holding task's base priority and the priority of the highest + priority task that is waiting to obtain the mutex. */ + if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask ) + { + uxPriorityToUse = uxHighestPriorityWaitingTask; + } + else + { + uxPriorityToUse = pxTCB->uxBasePriority; + } + + /* Does the priority need to change? */ + if( pxTCB->uxPriority != uxPriorityToUse ) + { + /* Only disinherit if no other mutexes are held. This is a + simplification in the priority inheritance implementation. If + the task that holds the mutex is also holding other mutexes then + the other mutexes may have caused the priority inheritance. */ + if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld ) + { + /* If a task has timed out because it already holds the + mutex it was trying to obtain then it cannot of inherited + its own priority. */ + configASSERT( pxTCB != pxCurrentTCB ); + + /* Disinherit the priority, remembering the previous + priority to facilitate determining the subject task's + state. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + uxPriorityUsedOnEntry = pxTCB->uxPriority; + pxTCB->uxPriority = uxPriorityToUse; + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the running task is not the task that holds the mutex + then the task that holds the mutex could be in either the + Ready, Blocked or Suspended states. Only remove the task + from its current state list if it is in the Ready state as + the task's priority is going to change and there is one + Ready list per priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + function so assert() if it is being called from an interrupt + context. Only API functions that end in "FromISR" can be used in an + interrupt. Only assert if the critical nesting count is 1 to + protect against recursive calls if the assert function also uses a + critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) + { + size_t x; + + /* Start by copying the entire string. */ + strcpy( pcBuffer, pcTaskName ); + + /* Pad the end of the string with spaces to ensure columns line up when + printed out. */ + for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + { + pcBuffer[ x ] = ' '; + } + + /* Terminate. */ + pcBuffer[ x ] = ( char ) 0x00; + + /* Return the new end of string. */ + return &( pcBuffer[ x ] ); + } +#endif /* << EST not used */ +#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskList( char * pcWriteBuffer, size_t bufSize ) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! if + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eRunning: cStatus = tskRUNNING_CHAR; + break; + + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + case eInvalid: /* Fall through. */ + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = ( char ) 0x00; + break; + } + +#if 0 /* << EST */ + /* Write the task name to the string, padding with spaces so it + can be printed in tabular form more easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + /* Write the rest of the string. */ + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#else /* << EST */ + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)cStatus); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].uxCurrentPriority); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].usStackHighWaterMark); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].xTaskNumber); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\r\n"); +#endif + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + uint32_t ulTotalTime, ulStatsAsPercentage; + + #if( configUSE_TRACE_FACILITY != 1 ) + { + #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). + } + #endif + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! If + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0UL ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + +#if 0 /* << EST */ + /* Write the task name to the string, padding with + spaces so it can be printed in tabular form more + easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); +#else + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); +#endif + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, ulStatsAsPercentage); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"%\r\n"); +#endif + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t<1%\r\n"); +#endif + } + #endif + } +#if 0 /* << EST */ + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#endif + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ +TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + TaskHandle_t pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) + { + uint32_t ulReturn; + + taskENTER_CRITICAL(); + { + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue == 0UL ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_TAKE_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_TAKE(); + ulReturn = pxCurrentTCB->ulNotifiedValue; + + if( ulReturn != 0UL ) + { + if( xClearCountOnExit != pdFALSE ) + { + pxCurrentTCB->ulNotifiedValue = 0UL; + } + else + { + pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + set by the notifying task or interrupt. This can be used to + clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry; + + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_WAIT_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_WAIT(); + + if( pulNotificationValue != NULL ) + { + /* Output the current notification value, which may or may not + have changed. */ + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue; + } + + /* If ucNotifyValue is set then either the task never entered the + blocked state (because a notification was already pending) or the + task unblocked because of a notification. Otherwise the task + unblocked because of a timeout. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* A notification was not received. */ + xReturn = pdFALSE; + } + else + { + /* A notification was already pending or a notification was + received while the task was waiting. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit; + xReturn = pdTRUE; + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) + { + TCB_t * pxTCB; + BaseType_t xReturn = pdPASS; + uint8_t ucOriginalNotifyState; + + configASSERT( xTaskToNotify ); + pxTCB = xTaskToNotify; + + taskENTER_CRITICAL(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction: + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + + break; + } + + traceTASK_NOTIFY(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + xNextTaskUnblockTime might be set to the blocked task's time + out time. If the task is unblocked for a reason other than + a timeout xNextTaskUnblockTime is normally left unchanged, + because it will automatically get reset to a new value when + the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter + sleep mode at the earliest possible time - so reset + xNextTaskUnblockTime here to ensure it is updated at the + earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + BaseType_t xReturn = pdPASS; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction : + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + break; + } + + traceTASK_NOTIFY_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter to an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + /* 'Giving' is equivalent to incrementing a count in a counting + semaphore. */ + ( pxTCB->ulNotifiedValue )++; + + traceTASK_NOTIFY_GIVE_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter in an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ + +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + BaseType_t xReturn; + + /* If null is passed in here then it is the calling task that is having + its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) + { + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t xTaskGetIdleRunTimeCounter( void ) + { + return xIdleTaskHandle->ulRunTimeCounter; + } +#endif +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) +{ +TickType_t xTimeToWake; +const TickType_t xConstTickCount = xTickCount; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + /* About to enter a delayed list, so ensure the ucDelayAborted flag is + reset to pdFALSE so it can be detected as having been set to pdTRUE + when the task leaves the Blocked state. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Remove the task from the ready list before adding it to the blocked list + as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); /*lint !e931 pxCurrentTCB cannot change as it is the calling task. pxCurrentTCB->uxPriority and uxTopReadyPriority cannot change as called with scheduler suspended or in a critical section. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure it is not woken by a timing event. It will block + indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + kernel will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow + list. */ + traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); /* << EST */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list + is used. */ + traceMOVED_TASK_TO_DELAYED_LIST(); /* << EST */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the + head of the list of blocked tasks then xNextTaskUnblockTime + needs to be updated too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the kernel + will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ + ( void ) xCanBlockIndefinitely; + } + #endif /* INCLUDE_vTaskSuspend */ +} + +/* Code below here allows additional code to be inserted into this source file, +especially where access to file scope functions and data is needed (for example +when performing module tests). */ + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + + +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) /* << EST test on trace */ + + #include "freertos_tasks_c_additions.h" + + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + static void freertos_tasks_c_additions_init( void ) + { + FREERTOS_TASKS_C_ADDITIONS_INIT(); + } + #endif + +#endif + +#if 1 /* << EST: additional functionality to iterathe through task handles. */ +static void prvCollectTaskHandlesWithinSingleList( List_t *pxList, TaskHandle_t taskHandleArray[], UBaseType_t noTaskHandlesInArray, UBaseType_t *idxCounter) +{ + TCB_t *pxNextTCB, *pxFirstTCB; + + /* This function is called with the scheduler suspended. */ + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + if (*idxCounter ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Search the suspended list. */ + prvCollectTaskHandlesWithinSingleList( &xSuspendedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Search the deleted list. */ + prvCollectTaskHandlesWithinSingleList( &xTasksWaitingTermination, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + } + ( void ) xTaskResumeAll(); + return idxCounter; +} + +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated) +{ + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the that + called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); +#if ( portSTACK_GROWTH > 0 ) + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxEndOfStack; +#elif (configRECORD_STACK_HIGH_ADDRESS == 1) + *ppxStart = pxTCB->pxEndOfStack; + *ppxEnd = pxTCB->pxStack; +#else /* no stack end information, return a zero size */ + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxStack; +#endif + *ppxTopOfStack = (StackType_t*)pxTCB->pxTopOfStack; +#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + *pucStaticallyAllocated = pxTCB->ucStaticallyAllocated; +#elif (configSUPPORT_STATIC_ALLOCATION && !configSUPPORT_DYNAMIC_ALLOCATION) /* only static allocation */ + *pucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; +#else /* only configSUPPORT_DYNAMIC_ALLOCATION */ + *pucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; +#endif + } + taskEXIT_CRITICAL(); +} +#endif /* << EST end */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.c new file mode 100644 index 0000000..1199d32 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.c @@ -0,0 +1,1111 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( TickType_t ) 0U + +/* The name assigned to the timer service task. This can be overridden by +defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configTIMER_SERVICE_TASK_NAME + #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" +#endif + +/* Bit definitions used in the ucStatus member of a timer structure. */ +#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) +#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) +#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + +#define TIMER_LEGACY_API (1) /* << EST: needed to have TAD working */ + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ +#if TIMER_LEGACY_API /* << EST */ + UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ +#endif + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ +} xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t +name below to enable the use of older kernel aware debuggers. */ +typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. +Two types of message can be queued - messages that manipulate a software timer, +and messages that request the execution of a non-timer related callback. The +two message types are defined in two separate structures, xTimerParametersType +and xCallbackParametersType respectively. */ +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier +that is used to determine which message type is valid. */ +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access these lists. +xActiveTimerList1 and xActiveTimerList2 could be at function scope but that +breaks some kernel aware debuggers, and debuggers that reply on removing the +static qualifier. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; +PRIVILEGED_DATA static List_t *pxCurrentTimerList; +PRIVILEGED_DATA static List_t *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; +PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + /* If static allocation is supported then the application must provide the + following callback function - which enables the application to optionally + provide the memory that will be used by the timer task as the task's stack + and TCB. */ + extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + +#endif + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * Called after a Timer_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +BaseType_t xTimerCreateTimerTask( void ) +{ +BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxTimerTaskTCBBuffer = NULL; + StackType_t *pxTimerTaskStackBuffer = NULL; + uint32_t ulTimerTaskStackSize; + + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + ulTimerTaskStackSize, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + pxTimerTaskStackBuffer, + pxTimerTaskTCBBuffer ); + + if( xTimerTaskHandle != NULL ) + { + xReturn = pdPASS; + } + } + #else + { + xReturn = xTaskCreate( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + configTIMER_TASK_STACK_DEPTH, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + &xTimerTaskHandle ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) + { + Timer_t *pxNewTimer; + + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */ + + if( pxNewTimer != NULL ) + { + /* Status is thus far zero as the timer is not created statically + and has not been started. The autoreload bit may get set in + prvInitialiseNewTimer. */ + pxNewTimer->ucStatus = 0x00; + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) + { + Timer_t *pxNewTimer; + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTimer_t equals the size of the real timer + structure. */ + volatile size_t xSize = sizeof( StaticTimer_t ); + configASSERT( xSize == sizeof( Timer_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ + configASSERT( pxTimerBuffer ); + pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */ + + if( pxNewTimer != NULL ) + { + /* Timers can be created statically or dynamically so note this + timer was created statically in case it is later deleted. The + autoreload bit may get set in prvInitialiseNewTimer(). */ + pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; + + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) +{ + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function + parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + if( uxAutoReload != pdFALSE ) + { + pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } +#if TIMER_LEGACY_API /* << EST */ + pxNewTimer->uxAutoReload = uxAutoReload; +#endif + traceTIMER_CREATE( pxNewTimer ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) +{ +BaseType_t xReturn = pdFAIL; +DaemonTaskMessage_t xMessage; + + configASSERT( xTimer ); + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) +{ + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->xTimerPeriodInTicks; +} +/*-----------------------------------------------------------*/ + +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) +{ +Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + taskENTER_CRITICAL(); + { + if( uxAutoReload != pdFALSE ) + { + pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD; + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) +{ +Timer_t * pxTimer = xTimer; +TickType_t xReturn; + + configASSERT( xTimer ); + xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->pcTimerName; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) +{ +BaseType_t xResult; +Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* The timer is inserted into a list using a time relative to anything + other than the current time. It will therefore be inserted into the + correct list relative to the time this task thinks it is now. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + mtCOVERAGE_TEST_MARKER(); + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvTimerTask, pvParameters ) +{ +TickType_t xNextExpireTime; +BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + { + extern void vApplicationDaemonTaskStartupHook( void ); + + /* Allow the application writer to execute some code in the context of + this task at the point the task starts executing. This is useful if the + application includes initialisation code that would benefit from + executing after the scheduler has been started. */ + vApplicationDaemonTaskStartupHook(); + } + #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) +{ +TickType_t xTimeNow; +BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + if( xListWasEmpty != pdFALSE ) + { + /* The current timer list is empty - is the overflow list + also empty? */ + xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); + } + + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the + block time to expire. If a command arrived between the + critical section being exited and this yield then the yield + will not cause the task to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) +{ +TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) +{ +TickType_t xTimeNow; +PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) +{ +BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +DaemonTaskMessage_t xMessage; +Timer_t *pxTimer; +BaseType_t xTimerListsWereSwitched, xResult; +TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + case tmrCOMMAND_START_FROM_ISR : + case tmrCOMMAND_RESET : + case tmrCOMMAND_RESET_FROM_ISR : + case tmrCOMMAND_START_DONT_TRACE : + /* Start or restart a timer. */ + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + timer list. Process it now. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + traceTIMER_EXPIRED( pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + break; + + case tmrCOMMAND_STOP : + case tmrCOMMAND_STOP_FROM_ISR : + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + break; + + case tmrCOMMAND_CHANGE_PERIOD : + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + be longer or shorter than the old one. The command time is + therefore set to the current time, and as the period cannot + be zero the next expiry time can only be in the future, + meaning (unlike for the xTimerStart() case above) there is + no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* The timer has already been removed from the active list, + just free up the memory if the memory was dynamically + allocated. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) + { + vPortFree( pxTimer ); + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + } + #else + { + /* If dynamic allocation is not enabled, the memory + could not have been dynamically allocated. So there is + no need to free the memory - just mark the timer as + "not active". */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default : + /* Don't expect to get here. */ + break; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( void ) +{ +TickType_t xNextExpireTime, xReloadTime; +List_t *pxTemp; +Timer_t *pxTimer; +BaseType_t xResult; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The timer queue is allocated statically in case + configSUPPORT_DYNAMIC_ALLOCATION is 0. */ + static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + + xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); + } + #else + { + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + } + #endif + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) +{ +BaseType_t xReturn; +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) +{ +Timer_t * const pxTimer = xTimer; +void *pvReturn; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pvReturn = pxTimer->pvTimerID; + } + taskEXIT_CRITICAL(); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) +{ +Timer_t * const pxTimer = xTimer; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pxTimer->pvTimerID = pvNewID; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* This function can only be called after a timer has been created or + after the scheduler has been started because, until then, the timer + queue does not exist. */ + configASSERT( xTimerQueue ); + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) + { + return ( ( Timer_t * ) xTimer )->uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) + { + ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.h new file mode 100644 index 0000000..a6f9324 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/timers.h @@ -0,0 +1,1296 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); + * + * Updates a timer to be either an autoreload timer, in which case the timer + * automatically resets itself each time it expires, or a one shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/tracealyzer_readme.txt b/Projects/tinyK22_OpenPnP_Master/Generated_Code/tracealyzer_readme.txt new file mode 100644 index 0000000..d0150eb --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/tracealyzer_readme.txt @@ -0,0 +1,288 @@ +------------------------------------------------------------------------------- + Tracealyzer for FreeRTOS - Trace Recorder Library v3.3.0 +------------------------------------------------------------------------------- + +Tracealyzer for FreeRTOS is a sophisticated tool for tracing and visualization +of FreeRTOS-based software systems. + +Tracealyzer gives an unprecedented insight into the runtime behavior, which +speeds up debugging, validation and optimization. + +This, the Trace Recorder Library, is the target-side part of Tracealyzer, that +performs the actual tracing. The resulting data can then be viewed in the +Tracealyzer PC application, found at https://percepio.com/tracealyzer + +To learn more, see these links. + + - Getting Started (videos etc): https://percepio.com/gettingstarted + + - User Manual (incl. Recorder API): https://percepio.com/docs/FreeRTOS/manual + + - FAQ: https://percepio.com/category/faq + +In case you have any questions, don't hesitate to contact support@percepio.com + +Tracealyzer supports FreeRTOS v7.3 and newer, including Amazon FreeRTOS. + +------------------------------------------------------------------------------- + +Changes, v3.2.0 -> v3.3.0 + +- Added support for FreeRTOS v10, including the new object types Message Buffer + and Stream Buffer. + +- Improved the object-level filtering to also support Timer, Event Group, + Message Buffer and Stream Buffer objects. + +- Fixed a few remaining build problems with older FreeRTOS versions (v7.x). + +- vTraceStoreISRBegin now reports an error on invalid handles, i.e., if the + initialization of the handle (xTraceSetISRProperties) had not been made. + +------------------------------------------------------------------------------- + +Changes, v3.1.2 -> v3.2.0 + +- Added new filtering system - that works in both snapshot and streaming mode. + Filtering was previously not supported in streaming mode, but can be very + useful for slower streaming interfaces. By exluding irrelevant events, the + amount of data produced can be reduced a lot. + + * New functions vTraceSetFilterGroup and vTraceSetFilterMask allows for + excluding all events from specific objects (like a semaphore or queue). + + * Added new "generic" filters (preprocessor level) to trcConfig.h, that + exclude all events of a particular types. + - TRC_CFG_INCLUDE_NOTIFY_EVENTS + - TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + - TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + - TRC_CFG_INCLUDE_TIMER_EVENTS + + * Upgraded some previous filters from "Snapshot only" to the Common API + and thereby moved them from trcSnapshotConfig.h to trcConfig.h. + - TRC_CFG_SCHEDULING_ONLY + - TRC_CFG_INCLUDE_MEMMANG_EVENTS + - TRC_CFG_INCLUDE_USER_EVENTS + - TRC_CFG_INCLUDE_ISR_TRACING + - TRC_CFG_INCLUDE_READY_EVENTS + - TRC_CFG_INCLUDE_OSTICK_EVENTS + + * Removed the old filter system from trcSnapshotRecorder.c. + +- Improved streaming interface - Now only two (2) macros are needed to be + defined in most cases, read and write. This makes it a lot easier to make + custom stream ports. + + * Many definitions that were identical in most stream ports, have been + replaced by default definitions in the recorder core. If needed, they + can be overriden by custom definitions in trcStreamingPort.h. + + * Stream ports are now assumed to use recorder's internal event buffer. + Other stream ports that writes directly to the streaming interface + (like J-Link) should define TRC_STREAM_PORT_USE_INTERNAL_BUFFER + as zero (0) to make it work correctly. + + * Macro TRC_STREAM_PORT_PERIODIC_SEND_DATA has been replaced by + TRC_STREAM_PORT_WRITE_DATA. Together with TRC_STREAM_PORT_READ_DATA, + this is all that is necessary for a typical stream port. + + * Return values from the stream port macros READ_DATA and WRITE_DATA are + now checked. Expects 0 on success, anything else produces a warning + that can be retrived using xTraceGetLastError() and also seen in + Tracealyzer if a trace was produced. + + * Stream ports should no longer call prvPagedEventBufferInit explicitly + (e.g. in TRC_STREAM_PORT_ON_TRACE_BEGIN). This is now called + automatically if TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1. + + * Macros TRC_STREAM_PORT_ON_TRACE_BEGIN and TRC_STREAM_PORT_ON_TRACE_END + are now unused by default and don't need to be defined. + You can however use them to hook in some own function at these events. + +- Added two new stream ports + + * TCPIP-Win32: allows for testing the streaming on Windows ports of your + RTOS, using Winsock. + + * File: example of streaming to a local file system (tested on Windows, + but easy to modify). + +- Added support for FreeRTOS v9.0.1 + + * Replaced FreeRTOS version code TRC_FREERTOS_VERSION_9_X with + - TRC_FREERTOS_VERSION_9_0_0 + - TRC_FREERTOS_VERSION_9_0_1 + + * Using TRC_FREERTOS_VERSION_9_X is no longer allowed. + +- Added additional events for xQueuePeek, for blocking and timeouts events. + +- Added event for traceTIMER_EXPIRED, showing when the timer callback + function is called. + +- Improved diagnostics in streaming mode, in case of errors in the recorder. + + * Added prvTraceWarning() - registers a "warning" error code, without + stopping the recorder. Called if READ_DATA or WRITE_DATA returns a + non-zero value, and in several other cases where the recorder + configuration is incorrect (e.g., too small symbol table). + + * Added several new warning codes (PSF_WARNING_XYZ), corresponding to the + issues detected by prvCheckRecorderStatus. + + * Fixed duplicate definitions of warning messages, so the warnings reported + to Tracealyzer are the same as those provided in xTraceGetLastError(). + + * Added better explainations of warning/error messages in the body of + xTraceGetLastError (in streaming mode). + +- Added xTraceIsRecordingEnabled() to Common API. + +- Added "unofficial" hardware port for Altera Nios-II. + This is a user contribition, not yet verified by Percerpio. + +- Fixed bug in vTraceEnable - option TRC_START_AWAIT_HOST was ignored if already initialized. + +- Fixed a few remaining compiler warnings. + +- Changed order of some settings in trcConfig.h - moved advanced stuff to the + bottom. + +- Removed SEGGER_RTT_Printf.c from the J-Link stream port since not required + for Tracealyzer. + +------------------------------------------------------------------------------- + +Changes, v3.1.1 -> v3.1.2 + +- Fixed two bugs related to User Events, one in vTracePrintF and other in vTracePrint. + +- Fixed a build problem related to a single reference of the old FreeRTOS type "xTaskHandle", in trcKernelPort.c. + Changed to "TaskHandle_t", unless if using an older FreeRTOS kernel or the "compatibility mode". + +- Removed traceCREATE_MUTEX hook for FreeRTOS v9 or later (no longer required) + +- Updated the User Manual regarding snapshot trace via IAR Embedded Workbench. + +- Renamed vTraceGetTraceBuffer to xTraceGetTraceBuffer, since returning a pointer. + +------------------------------------------------------------------------------- + +Changes, v3.1.0 -> v3.1.1 + +After the major changes in the v3.1.0 trace recorder library, this update +corrects a number of minor issues. Only minor functional improvements. + +- You can now use TRC_ALLOC_CUSTOM_BUFFER to declare a trace buffer on a custom + location (using linker directives). + The related function vTraceSetRecorderDataBuffer has been promoted to the + Common API (previously only supported in snapshot mode, but custom allocation + is now generally supported also in streaming mode). + +- Removed TRC_CFG_USE_LINKER_PRAGMA. No longer necessary thanks to the custom + allocation mode. + +- Added support for timestamping from custom periodic timers, required for + accurate timestamping on Cortex-M0/M0+ devices when using tickless idle. + Only for streaming mode so far. See TRC_CUSTOM_TIMER_INCR / DECR. + +- ARM Cortex-M port: Made sure the DWT unit is initialized properly, in case + the debugger doesn't handle this. + +- ARM Cortex-M port: Added possibility to use Systick timestamping also on + Cortex-M3/M4/M7 devices (that otherwise use DWT timestamping by default). + To use this option, define the macro TRC_CFG_ARM_CM_USE_SYSTICK. + +- J-Link streaming: The default RTT buffer has been changed from 0 to 1. + +- J-Link streaming: The RTT buffer settings for buffer 1 and higher, are now + found in trcStreamingPort.h. Note: These settings don't apply to buffer 0. + +- vTracePrint has been optimized for better performance in string logging. + +- Minor performance improvement related to symbol table transfer in streaming mode. + +- Timer names now registered also in streaming mode. + +- Timer start and stop event are now traced. + +- Implemented support for queue registry (traceQUEUE_REGISTRY_ADD) also for streaming. + +- Fixed a bug related to repeated calls of vTraceEnable. + +- Fixed a bug where task-switches seemed to occur even though the scheduler was disabled. + +- Renamed HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48, added prefix TRC. + +- Fixed several language issues in the comments and documentation. + +- Fixed several minor issues and warnings from different compilers + (including PowerPC/gcc) and configurations. + +------------------------------------------------------------------------------- + +Changes, v3.0.9 -> v3.1.0 + +- Merge of previously separated snapshot and streaming recorders into a single + recorder supporting both streaming and snapshot as different modes. + +- New common API for supporting both streaming and snapshot modes. + +- New integration guide, see the User Manual. + +- Major improvement of API documentation in source files and User Manual. + +- New concept of "stream ports", giving a better structure defining streaming + interfaces, and restructured the J-Link and TCP/IP streaming as stream ports. + +- Added a stream port for USB CDC connections, with STM32 as example. + Since Tracealyzer now can receive serial data on Windows COM ports, this is + really easy to use. + +- Added a warning (#error) for cases where FreeRTOS tickless idle mode is used + together with timestamping using SysTick or other periodic interrupt timers, + Tracing with tickless idle requires an independent time source to correctly + capture the length of the idle periods. + +- Major changes in the recorder API. Important examples are: + + * Some configuration macros have changed names, e.g. for "hardware port". + Make sure to remove any old "trcConfig.h" files if upgrading from an + earlier version! + + * Recorder configuration in trcConfig.h has been minimized and now only + includes the important settings that are independent of recorder mode. + Advanced settings for each mode are found in trcSnapshotConfig.h and + trcStreamingConfig.h. + + * vTraceEnable replaces Trace_Init and vTraceInitTraceData, as well as + vTraceStart and uiTraceStart. + + * vTraceStop now part of the common API and thereby available also in + streaming. And since vTraceEnable can start the streaming directly + you have the option control the tracing from target, e.g., for + streaming to a device file system. + + * vTraceStoreKernelObjectName from old streaming recorder has been replaced + by vTraceSetQueueName, vTraceSetSemaphoreName, etc. + + * vTraceSetISRProperties now returns a "traceHandle" that should be passed as + parameter to vTraceStoreISRBegin and vTraceStoreISREnd. + + * xTraceRegisterString has replaced the old functions xTraceOpenLabel and + vTraceStoreUserEventChannelName. This now returns a "traceString" for use + as "channel" parameter in vTracePrintF, and in other places where strings + are stored. + + * Removed vTraceStoreISREndManual and vTraceStoreISREndAuto, use + vTraceStoreISREnd instead. + + * Renamed the functions for saving User Events in a separate buffer: + - xTraceRegisterChannelFormat -> xTraceRegisterUBChannel + - vTraceChannelPrintF -> vTraceUBData + - vTraceChannelUserEvent -> vTraceUBEvent + + +------------------------------------------------------------------------------- +Copyright Percepio AB, 2017. + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcConfig.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcConfig.h new file mode 100644 index 0000000..884674d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcConfig.h @@ -0,0 +1,380 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcConfig.h + * + * Main configuration parameters for the trace recorder library. + * More settings can be found in trcStreamingConfig.h and trcSnapshotConfig.h. + * + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2016. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_CONFIG_H +#define TRC_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "trcPortDefines.h" + +/****************************************************************************** + * Include of processor header file + * + * Here you may need to include the header file for your processor. This is + * required at least for the ARM Cortex-M port, that uses the ARM CMSIS API. + * Try that in case of build problems. Otherwise, remove the #error line below. + *****************************************************************************/ +#if 1 /* << EST */ + #include "MCUC1.h" /* include SDK and API used */ + #include "FreeRTOSConfig.h" + + #if MCUC1_CONFIG_PEX_SDK_USED + #ifndef __CORTEX_M + #if configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) + #define __CORTEX_M 0 + #elif configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define __CORTEX_M 4 + #elif configCPU_FAMILY_IS_ARM_M7(configCPU_FAMILY) + #define __CORTEX_M 7 + #endif + #endif + #endif +#else + #error "Trace Recorder: Please include your processor's header file here and remove this line." +#endif + +/******************************************************************************* + * Configuration Macro: TRC_CFG_HARDWARE_PORT + * + * Specify what hardware port to use (i.e., the "timestamping driver"). + * + * All ARM Cortex-M MCUs are supported by "TRC_HARDWARE_PORT_ARM_Cortex_M". + * This port uses the DWT cycle counter for Cortex-M3/M4/M7 devices, which is + * available on most such devices. In case your device don't have DWT support, + * you will get an error message opening the trace. In that case, you may + * force the recorder to use SysTick timestamping instead, using this define: + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + * + * For ARM Cortex-M0/M0+ devices, SysTick mode is used automatically. + * + * See trcHardwarePort.h for available ports and information on how to + * define your own port, if not already present. + ******************************************************************************/ +#if 1 /* << EST */ +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_ARM_Cortex_M +#else + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_PROCESSOR_EXPERT +#endif +#else + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET +#endif + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_MODE + * + * Specify what recording mode to use. Snapshot means that the data is saved in + * an internal RAM buffer, for later upload. Streaming means that the data is + * transferred continuously to the host PC. + * + * For more information, see http://percepio.com/2016/10/05/rtos-tracing/ + * and the Tracealyzer User Manual. + * + * Values: + * TRC_RECORDER_MODE_SNAPSHOT + * TRC_RECORDER_MODE_STREAMING + ******************************************************************************/ +#define TRC_CFG_RECORDER_MODE TRC_RECORDER_MODE_STREAMING + +/****************************************************************************** + * TRC_CFG_FREERTOS_VERSION + * + * Specify what version of FreeRTOS that is used (don't change unless using the + * trace recorder library with an older version of FreeRTOS). + * + * TRC_FREERTOS_VERSION_7_3 If using FreeRTOS v7.3.x + * TRC_FREERTOS_VERSION_7_4 If using FreeRTOS v7.4.x + * TRC_FREERTOS_VERSION_7_5_OR_7_6 If using FreeRTOS v7.5.0 - v7.6.0 + * TRC_FREERTOS_VERSION_8_X If using FreeRTOS v8.X.X + * TRC_FREERTOS_VERSION_9_0_0 If using FreeRTOS v9.0.0 + * TRC_FREERTOS_VERSION_9_0_1 If using FreeRTOS v9.0.1 + * TRC_FREERTOS_VERSION_9_0_2 If using FreeRTOS v9.0.2 + * TRC_FREERTOS_VERSION_10_0_0 If using FreeRTOS v10.0.0 or later + *****************************************************************************/ +#define TRC_CFG_FREERTOS_VERSION TRC_FREERTOS_VERSION_10_0_0 + +/******************************************************************************* + * TRC_CFG_SCHEDULING_ONLY + * + * Macro which should be defined as an integer value. + * + * If this setting is enabled (= 1), only scheduling events are recorded. + * If disabled (= 0), all events are recorded (unless filtered in other ways). + * + * Default value is 0 (= include additional events). + ******************************************************************************/ +#define TRC_CFG_SCHEDULING_ONLY 0 + + /****************************************************************************** + * TRC_CFG_INCLUDE_MEMMANG_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * This controls if malloc and free calls should be traced. Set this to zero (0) + * to exclude malloc/free calls, or one (1) to include such events in the trace. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_MEMMANG_EVENTS 1 + + /****************************************************************************** + * TRC_CFG_INCLUDE_USER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), all code related to User Events is excluded in order + * to reduce code size. Any attempts of storing User Events are then silently + * ignored. + * + * User Events are application-generated events, like "printf" but for the + * trace log, generated using vTracePrint and vTracePrintF. + * The formatting is done on host-side, by Tracealyzer. User Events are + * therefore much faster than a console printf and can often be used + * in timing critical code without problems. + * + * Note: In streaming mode, User Events are used to provide error messages + * and warnings from the recorder (in case of incorrect configuration) for + * display in Tracealyzer. Disabling user events will also disable these + * warnings. You can however still catch them by calling xTraceGetLastError + * or by putting breakpoints in prvTraceError and prvTraceWarning. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_USER_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_ISR_TRACING + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the code for recording Interrupt Service Routines is + * excluded, in order to reduce code size. + * + * Default value is 1. + * + * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin + * and vTraceStoreISREnd in your interrupt handlers. + *****************************************************************************/ + +/***************************************************************************** + * TRC_CFG_INCLUDE_ISR_TRACING + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the code for recording Interrupt Service Routines is + * excluded, in order to reduce code size. + * + * Default value is 1. + * + * Note: tracing ISRs requires that you insert calls to vTraceStoreISRBegin + * and vTraceStoreISREnd in your interrupt handlers. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_ISR_TRACING 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_READY_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If one (1), events are recorded when tasks enter scheduling state "ready". + * This allows Tracealyzer to show the initial pending time before tasks enter + * the execution state, and present accurate response times. + * If zero (0), "ready events" are not created, which allows for recording + * longer traces in the same amount of RAM. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_READY_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_OSTICK_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is one (1), events will be generated whenever the OS clock is + * increased. If zero (0), OS tick events are not generated, which allows for + * recording longer traces in the same amount of RAM. + * + * Default value is 1. + *****************************************************************************/ + +#define TRC_CFG_INCLUDE_OSTICK_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "pending function call" + * events, such as xTimerPendFunctionCall(). + * + * Default value is 0 since dependent on timers.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any "event group" events. + * + * Default value is 0 (excluded) since dependent on event_groups.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 1 + + /***************************************************************************** + * TRC_CFG_INCLUDE_TIMER_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the trace will exclude any Timer events. + * + * Default value is 0 since dependent on timers.c + *****************************************************************************/ +#define TRC_CFG_INCLUDE_TIMER_EVENTS 0 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RECORDER_BUFFER_ALLOCATION + * + * Specifies how the recorder buffer is allocated (also in case of streaming, in + * port using the recorder's internal temporary buffer) + * + * Values: + * TRC_RECORDER_BUFFER_ALLOCATION_STATIC - Static allocation (internal) + * TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC - Malloc in vTraceEnable + * TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM - Use vTraceSetRecorderDataBuffer + * + * Static and dynamic mode does the allocation for you, either in compile time + * (static) or in runtime (malloc). + * The custom mode allows you to control how and where the allocation is made, + * for details see TRC_ALLOC_CUSTOM_BUFFER and vTraceSetRecorderDataBuffer(). + ******************************************************************************/ +#define TRC_CFG_RECORDER_BUFFER_ALLOCATION TRC_RECORDER_BUFFER_ALLOCATION_STATIC + +/****************************************************************************** + * TRC_CFG_MAX_ISR_NESTING + * + * Defines how many levels of interrupt nesting the recorder can handle, in + * case multiple ISRs are traced and ISR nesting is possible. If this + * is exceeded, the particular ISR will not be traced and the recorder then + * logs an error message. This setting is used to allocate an internal stack + * for keeping track of the previous execution context (4 byte per entry). + * + * This value must be a non-zero positive constant, at least 1. + * + * Default value: 8 + *****************************************************************************/ +#define TRC_CFG_MAX_ISR_NESTING 8 + +/* Specific configuration, depending on Streaming/Snapshot mode */ +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) +#include "trcSnapshotConfig.h" +#elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) +#include "trcStreamingConfig.h" +#endif + +/* << EST: additional configuration item */ +/****************************************************************************** + * TRC_CFG_TRACE_DESCRIPTION + * + * Macro which should be defined as a string. + * + * This string is stored in the trace and displayed in Tracealyzer. Can be + * used to store, e.g., system version or build date. This is also used to store + * internal error messages from the recorder, which if occurs overwrites the + * value defined here. This may be maximum 256 chars. + *****************************************************************************/ +#define TRC_CFG_TRACE_DESCRIPTION "FreeRTOS+Trace" + +/* << EST: additional configuration item */ +/****************************************************************************** + * TRC_CFG_TRACE_DESCRIPTION_MAX_LENGTH + * + * The maximum length (including zero termination) for the TRC_CFG_TRACE_DESCRIPTION + * string. Since this string also is used for internal error messages from the + * recorder do not make it too short, as this may truncate the error messages. + * Default is 80. + * Maximum allowed length is 256 - the trace will fail to load if longer. + *****************************************************************************/ +#define TRC_CFG_TRACE_DESCRIPTION_MAX_LENGTH 80 + +/****************************************************************************** + * TRC_CFG_INCLUDE_OBJECT_DELETE + * + * Macro which should be defined as either zero (0) or one (1). + * + * This must be enabled (1) if tasks, queues or other + * traced kernel objects are deleted at runtime. If no deletes are made, this + * can be set to 0 in order to exclude the delete-handling code. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_OBJECT_DELETE 1 + +/****************************************************************************** + * TRC_CFG_INCLUDE_QUEUE_EVENTS + * + * Macro which should be defined as either zero (0) or one (1). + * + * This must be enabled (1) for recording queue events. + * + * Default value is 1. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_QUEUE_EVENTS 1 +/* << EST: end additional configuration item */ + +#ifdef __cplusplus +} +#endif + +#endif /* _TRC_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcHardwarePort.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcHardwarePort.h new file mode 100644 index 0000000..93dc7d5 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcHardwarePort.h @@ -0,0 +1,517 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcHardwarePort.h + * + * The hardware abstraction layer for the trace recorder. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_HARDWARE_PORT_H +#define TRC_HARDWARE_PORT_H + +#include "trcPortDefines.h" + +#if 1 /* << EST */ +#include "FreeRTOSConfig.h" + +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) +#if MCUC1_CONFIG_PEX_SDK_USED/* << EST Kinetis SDK is using CMSIS core, therefore the functions below are defined in core_cmFunc.h. For non-SDK projects, define them locally here */ + /** \brief Get Priority Mask + This function returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ + __attribute__( ( always_inline ) ) static inline uint32_t __get_PRIMASK(void) + { + uint32_t result; + + __asm volatile ("MRS %0, primask" : "=r" (result) ); + return(result); + } + + + /** \brief Set Priority Mask + This function assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ + __attribute__( ( always_inline ) ) static inline void __set_PRIMASK(uint32_t priMask) + { + __asm volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); + } +#elif MCUC1_CONFIG_CPU_IS_STM32 + #include "stm32f3xx_hal.h" /* header file for STM32F303K8 */ +#elif MCUC1_CONFIG_CPU_IS_NORDIC_NRF + #include "nrf.h" /* header file Nordic devices */ +#else + #include "fsl_device_registers.h" +#endif /* #if MCUC1_CONFIG_PEX_SDK_USED */ +#endif /* configCPU_FAMILY_IS_ARM */ +#endif /* << EST */ + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET) + #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" +#endif + +/******************************************************************************* + * TRC_IRQ_PRIORITY_ORDER + * + * Macro which should be defined as an integer of 0 or 1. + * + * This should be 0 if lower IRQ priority values implies higher priority + * levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., + * if higher IRQ priority values means higher priority, this should be 1. + * + * This setting is not critical. It is used only to sort and colorize the + * interrupts in priority order, in case you record interrupts using + * the vTraceStoreISRBegin and vTraceStoreISREnd routines. + * + ****************************************************************************** + * + * HWTC Macros + * + * These macros provides a hardware isolation layer representing the + * hardware timer/counter used for the event timestamping. + * + * TRC_HWTC_COUNT: How to read the current value of the timer/counter. + * + * TRC_HWTC_TYPE: Tells the type of timer/counter used for TRC_HWTC_COUNT: + * + * - TRC_FREE_RUNNING_32BIT_INCR: + * Free-running 32-bit timer/counter, counting upwards from 0. + * + * - TRC_FREE_RUNNING_32BIT_DECR + * Free-running 32-bit timer/counter, counting downwards from 0xFFFFFFFF. + * + * - TRC_OS_TIMER_INCR + * Periodic timer that drives the OS tick interrupt, counting upwards + * from 0 until (TRC_HWTC_PERIOD-1). + * + * - TRC_OS_TIMER_DECR + * Periodic timer that drives the OS tick interrupt, counting downwards + * from TRC_HWTC_PERIOD-1 until 0. + * + * - TRC_CUSTOM_TIMER_INCR + * A custom timer or counter independent of the OS tick, counting + * downwards from TRC_HWTC_PERIOD-1 until 0. (Currently only supported + * in streaming mode). + * + * - TRC_CUSTOM_TIMER_DECR + * A custom timer independent of the OS tick, counting downwards + * from TRC_HWTC_PERIOD-1 until 0. (Currently only supported + * in streaming mode). + * + * TRC_HWTC_PERIOD: The number of HWTC_COUNT ticks until the timer wraps + * around. If using TRC_FREE_RUNNING_32BIT_INCR/DECR, this should be 0. + * + * TRC_HWTC_FREQ_HZ: The clock rate of the TRC_HWTC_COUNT counter in Hz. If using + * TRC_OS_TIMER_INCR/DECR, this is should be TRC_HWTC_PERIOD * TRACE_TICK_RATE_HZ. + * If using a free-running timer, this is often TRACE_CPU_CLOCK_HZ (if running at + * the core clock rate). If using TRC_CUSTOM_TIMER_INCR/DECR, this should match + * the clock rate of your custom timer (i.e., TRC_HWTC_COUNT). If the default value + * of TRC_HWTC_FREQ_HZ is incorrect for your setup, you can override it by calling + * vTraceSetFrequency before calling vTraceEnable. + * + * TRC_HWTC_DIVISOR (used in snapshot mode only): + * In snapshot mode, the timestamp resolution is TRC_HWTC_FREQ_HZ/TRC_HWTC_DIVISOR. + * If the timer frequency is very high (hundreds of MHz), we recommend increasing + * the TRC_HWTC_DIVISOR prescaler, to reduce the bandwidth needed to store + * timestamps. This since extra "XTS" events are inserted if the time since the + * previous event exceeds a certain limit (255 or 65535 depending on event type). + * It is advised to keep the time between most events below 65535 native ticks + * (after division by TRC_HWTC_DIVISOR) to avoid frequent XTS events. + ******************************************************************************/ + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NOT_SET) + #error "TRC_CFG_HARDWARE_PORT not selected - see trcConfig.h" +#endif + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32) + /* This can be used as a template for any free-running 32-bit counter */ + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT (ulGetRunTimeCounterValue()) + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ 100000 + + #define TRC_IRQ_PRIORITY_ORDER 1 + + #define TRC_PORT_SPECIFIC_INIT() + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_HWIndependent) + /* Timestamping by OS tick only (typically 1 ms resolution) */ + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT 0 + #define TRC_HWTC_PERIOD 1 + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ TRACE_TICK_RATE_HZ + + /* Set the meaning of IRQ priorities in ISR tracing - see above */ + #define TRC_IRQ_PRIORITY_ORDER NOT_SET + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) + + #ifndef __CORTEX_M + #error "Can't find the CMSIS API. Please include your processor's header file in trcConfig.h" + #endif + + /************************************************************************** + * For Cortex-M3, M4 and M7, the DWT cycle counter is used for timestamping. + * For Cortex-M0 and M0+, the SysTick timer is used since DWT is not + * available. Systick timestamping can also be forced on Cortex-M3, M4 and + * M7 by defining the preprocessor directive TRC_CFG_ARM_CM_USE_SYSTICK, + * either directly below or in trcConfig.h. + * + * #define TRC_CFG_ARM_CM_USE_SYSTICK + **************************************************************************/ + + #if ((__CORTEX_M >= 0x03) && (! defined TRC_CFG_ARM_CM_USE_SYSTICK)) + + void prvTraceInitCortexM(void); + + #define TRC_REG_DEMCR (*(volatile uint32_t*)0xE000EDFC) + #define TRC_REG_DWT_CTRL (*(volatile uint32_t*)0xE0001000) + #define TRC_REG_DWT_CYCCNT (*(volatile uint32_t*)0xE0001004) + #define TRC_REG_DWT_EXCCNT (*(volatile uint32_t*)0xE000100C) + + #define TRC_REG_ITM_LOCKACCESS (*(volatile uint32_t*)0xE0001FB0) + #define TRC_ITM_LOCKACCESS_UNLOCK (0xC5ACCE55) + + /* Bit mask for TRCENA bit in DEMCR - Global enable for DWT and ITM */ + #define TRC_DEMCR_TRCENA (1 << 24) + + /* Bit mask for NOPRFCNT bit in DWT_CTRL. If 1, DWT_EXCCNT is not supported */ + #define TRC_DWT_CTRL_NOPRFCNT (1 << 24) + + /* Bit mask for NOCYCCNT bit in DWT_CTRL. If 1, DWT_CYCCNT is not supported */ + #define TRC_DWT_CTRL_NOCYCCNT (1 << 25) + + /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_EXCCNT */ + #define TRC_DWT_CTRL_EXCEVTENA (1 << 18) + + /* Bit mask for EXCEVTENA_ bit in DWT_CTRL. Set to 1 to enable DWT_CYCCNT */ + #define TRC_DWT_CTRL_CYCCNTENA (1) + + #define TRC_PORT_SPECIFIC_INIT() prvTraceInitCortexM() + + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_HWTC_COUNT TRC_REG_DWT_CYCCNT + #define TRC_HWTC_PERIOD 0 + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ + #define TRC_IRQ_PRIORITY_ORDER 0 + + #else + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT (*((volatile uint32_t*)0xE000E018)) + #define TRC_HWTC_PERIOD ((*((volatile uint32_t*)0xE000E014)) + 1) + #define TRC_HWTC_DIVISOR 4 + #define TRC_HWTC_FREQ_HZ TRACE_CPU_CLOCK_HZ + #define TRC_IRQ_PRIORITY_ORDER 0 + + #endif + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) + + #include "iodefine.h" + + #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT (CMT0.CMCNT) + + #elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + + /* Decreasing counters better for Tickless Idle? */ + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT (CMT0.CMCOR - CMT0.CMCNT) + + #endif + + #define TRC_HWTC_PERIOD (CMT0.CMCOR + 1) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT (TMR1) + #define TRC_HWTC_PERIOD (PR1 + 1) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48) + + #define TRC_RTIFRC0 *((uint32_t *)0xFFFFFC10) + #define TRC_RTICOMP0 *((uint32_t *)0xFFFFFC50) + #define TRC_RTIUDCP0 *((uint32_t *)0xFFFFFC54) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT (TRC_RTIFRC0 - (TRC_RTICOMP0 - TRC_RTIUDCP0)) + #define TRC_HWTC_PERIOD (TRC_RTIUDCP0) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_AT91SAM7) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ((uint32_t)(AT91C_BASE_PITC->PITC_PIIR & 0xFFFFF)) + #define TRC_HWTC_PERIOD ((uint32_t)(AT91C_BASE_PITC->PITC_PIMR + 1)) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Atmel_UC3A0) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO*/ + + /* For Atmel AVR32 (AT32UC3A) */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT ((uint32_t)sysreg_read(AVR32_COUNT)) + #define TRC_HWTC_PERIOD ((uint32_t)(sysreg_read(AVR32_COMPARE) + 1)) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_NXP_LPC210X) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + /* Tested with LPC2106, but should work with most LPC21XX chips. */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT *((uint32_t *)0xE0004008 ) + #define TRC_HWTC_PERIOD *((uint32_t *)0xE0004018 ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430) + + /* UNOFFICIAL PORT - NOT YET VERIFIED */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT (TA0R) + #define TRC_HWTC_PERIOD (((uint16_t)TACCR0)+1) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 1 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC405) + + /* UNOFFICIAL PORT - NOT YET VERIFIED */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT mfspr(0x3db) + #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_PPC440) + + /* UNOFFICIAL PORT */ + + /* This should work with most PowerPC chips */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT mfspr(0x016) + #define TRC_HWTC_PERIOD (TRACE_CPU_CLOCK_HZ / TRACE_TICK_RATE_HZ) + #define TRC_HWTC_DIVISOR 1 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_XILINX_MICROBLAZE) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + /* This should work with most Microblaze configurations. + * It uses the AXI Timer 0 - the tick interrupt source. + * If an AXI Timer 0 peripheral is available on your hardware platform, no modifications are required. + */ + #include "xtmrctr_l.h" + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT XTmrCtr_GetTimerCounterReg( XPAR_TMRCTR_0_BASEADDR, 0 ) + #define TRC_HWTC_PERIOD (XTmrCtr_mGetLoadReg( XPAR_TMRCTR_0_BASEADDR, 0) + 1) + #define TRC_HWTC_DIVISOR 16 + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + #include "system.h" + #include "sys/alt_timestamp.h" + + #define TRC_HWTC_TYPE TRC_OS_TIMER_INCR + #define TRC_HWTC_COUNT (uint32_t)alt_timestamp() + #define TRC_HWTC_PERIOD 0xFFFFFFFF + #define TRC_HWTC_FREQ_HZ TIMESTAMP_TIMER_FREQ + #define TRC_HWTC_DIVISOR 1 + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) + + /* INPUT YOUR PERIPHERAL BASE ADDRESS HERE */ + #define TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS 0xSOMETHING + + #define TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET 0x0600 + #define TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x00)) + #define TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x04)) + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG (*(volatile uint32_t*)(TRC_CA9_MPCORE_PERIPHERAL_BASE_ADDRESS + TRC_CA9_MPCORE_PRIVATE_MEMORY_OFFSET + 0x08)) + + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK 0x0000FF00 + #define TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT 8 + #define TRC_CA9_MPCORE_PRIVCTR_PRESCALER (((TRC_CA9_MPCORE_PRIVCTR_CONTROL_REG & TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_MASK) >> TRC_CA9_MPCORE_PRIVCTR_CONTROL_PRESCALER_SHIFT) + 1) + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + #define TRC_HWTC_COUNT TRC_CA9_MPCORE_PRIVCTR_COUNTER_REG + #define TRC_HWTC_PERIOD (TRC_CA9_MPCORE_PRIVCTR_PERIOD_REG + 1) + + /**************************************************************************************** + NOTE: The private timer ticks with a very high frequency (half the core-clock usually), + depending on the prescaler used. If a low prescaler is used, the number of HW ticks between + the trace events gets large, and thereby inefficient to store (sometimes extra events are + needed). To improve efficiency, you may use the TRC_HWTC_DIVISOR as an additional prescaler. + *****************************************************************************************/ + #define TRC_HWTC_DIVISOR 1 + + #define TRC_HWTC_FREQ_HZ (TRACE_TICK_RATE_HZ * TRC_HWTC_PERIOD) + #define TRC_IRQ_PRIORITY_ORDER 0 + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4) + + /* UNOFFICIAL PORT - NOT YET VERIFIED BY PERCEPIO */ + + #define TRC_HWTC_TYPE TRC_OS_TIMER_DECR + //#define HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING + #define TRC_HWTC_COUNT PIT.TIMER[configTICK_PIT_CHANNEL].CVAL.R // must be the PIT channel used for the systick + #define TRC_HWTC_PERIOD ((configPIT_CLOCK_HZ / configTICK_RATE_HZ) - 1U) // TODO FIXME or maybe not -1? what's the right "period" value? + #define TRC_HWTC_FREQ_HZ configPIT_CLOCK_HZ + #define TRC_HWTC_DIVISOR 1 + #define TRC_IRQ_PRIORITY_ORDER 1 // higher IRQ priority values are more significant + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_APPLICATION_DEFINED) + + #if !( defined (TRC_HWTC_TYPE) && defined (TRC_HWTC_COUNT) && defined (TRC_HWTC_PERIOD) && defined (TRC_HWTC_FREQ_HZ) && defined (TRC_IRQ_PRIORITY_ORDER) ) + #error "The hardware port is not completely defined!" + #endif + +#elif (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_PROCESSOR_EXPERT) /* << EST */ + #include "portTicks.h" /* << EST */ + +#elif (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET) + + #error "TRC_CFG_HARDWARE_PORT had unsupported value!" + #define TRC_CFG_HARDWARE_PORT TRC_HARDWARE_PORT_NOT_SET + +#endif + +#ifndef TRC_HWTC_DIVISOR + #define TRC_HWTC_DIVISOR 1 +#endif + +#ifndef TRC_PORT_SPECIFIC_INIT + #define TRC_PORT_SPECIFIC_INIT() +#endif + +/* If Win32 port */ +#ifdef WIN32 + + #undef _WIN32_WINNT + #define _WIN32_WINNT 0x0600 + + /* Standard includes. */ + #include + #include + #include + + /*************************************************************************** + * The Win32 port by default saves the trace to file and then kills the + * program when the recorder is stopped, to facilitate quick, simple tests + * of the recorder. + ***************************************************************************/ + #define WIN32_PORT_SAVE_WHEN_STOPPED 1 + #define WIN32_PORT_EXIT_WHEN_STOPPED 1 + +#endif + +#if (TRC_CFG_HARDWARE_PORT != TRC_HARDWARE_PORT_NOT_SET) + + #ifndef TRC_HWTC_TYPE + #error "TRC_HWTC_TYPE is not set!" + #endif + + #ifndef TRC_HWTC_COUNT + #error "TRC_HWTC_COUNT is not set!" + #endif + + #ifndef TRC_HWTC_PERIOD + #error "TRC_HWTC_PERIOD is not set!" + #endif + + #ifndef TRC_HWTC_DIVISOR + #error "TRC_HWTC_DIVISOR is not set!" + #endif + + #ifndef TRC_IRQ_PRIORITY_ORDER + #error "TRC_IRQ_PRIORITY_ORDER is not set!" + #elif (TRC_IRQ_PRIORITY_ORDER != 0) && (TRC_IRQ_PRIORITY_ORDER != 1) + #error "TRC_IRQ_PRIORITY_ORDER has bad value!" + #endif + + #if (TRC_HWTC_DIVISOR < 1) + #error "TRC_HWTC_DIVISOR must be a non-zero positive value!" + #endif + + #ifndef TRC_HWTC_FREQ_HZ + #error "TRC_HWTC_FREQ_HZ not defined!" + #endif + +#endif + +#endif /*TRC_SNAPSHOT_HARDWARE_PORT_H*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.c new file mode 100644 index 0000000..e246929 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.c @@ -0,0 +1,806 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcKernelPort.c + * + * The FreeRTOS-specific parts of the trace recorder + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#include "FreeRTOS.h" +#if configUSE_PERCEPIO_TRACE_HOOKS /* << EST: FreeRTOS using Percepio Trace */ + +#if (!defined(TRC_USE_TRACEALYZER_RECORDER) && configUSE_TRACE_FACILITY == 1) +#error Trace Recorder: You need to include trcRecorder.h at the end of your FreeRTOSConfig.h! +#endif + +#if (defined(TRC_USE_TRACEALYZER_RECORDER) && TRC_USE_TRACEALYZER_RECORDER == 1) + +#if (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) + /* + The below error message is to alert you on the following issue: + + The hardware port selected in trcConfig.h uses the operating system timer for the + timestamping, i.e., the periodic interrupt timer that drives the OS tick interrupt. + + When using "tickless idle" mode, the recorder needs an independent time source in + order to correctly record the durations of the idle times. Otherwise, the trace may appear + to have a different length than in reality, and the reported CPU load is also affected. + + You may override this warning by defining the TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING + macro in your trcConfig.h file. But then the time scale may be incorrect during + tickless idle periods. + + To get this correct, override the default timestamping by setting TRC_CFG_HARDWARE_PORT + in trcConfig.h to TRC_HARDWARE_PORT_APPLICATION_DEFINED and define the HWTC macros + accordingly, using a free running counter or an independent periodic interrupt timer. + See trcHardwarePort.h for details. + + For ARM Cortex-M3, M4 and M7 MCUs this is not an issue, since the recorder uses the + DWT cycle counter for timestamping in these cases. + */ + + #ifndef TRC_CFG_ACKNOWLEDGE_TICKLESS_IDLE_WARNING + #error Trace Recorder: This timestamping mode is not recommended with Tickless Idle. + #endif +#endif /* (configUSE_TICKLESS_IDLE != 0 && (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) */ + +#include "task.h" +#include "queue.h" + +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +/* If the project does not include the FreeRTOS timers, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ +#include "timers.h" +#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ + +#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +/* If the project does not include the FreeRTOS event groups, TRC_CFG_INCLUDE_TIMER_EVENTS must be set to 0 */ +#include "event_groups.h" +#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#include "stream_buffer.h" +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +uint32_t prvTraceGetQueueNumber(void* handle); + +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) + +extern unsigned char ucQueueGetQueueNumber( xQueueHandle pxQueue ); +extern void vQueueSetQueueNumber( xQueueHandle pxQueue, unsigned char ucQueueNumber ); +extern unsigned char ucQueueGetQueueType( xQueueHandle pxQueue ); + +uint32_t prvTraceGetQueueNumber(void* handle) +{ + return (uint32_t)ucQueueGetQueueNumber(handle); +} +#else +uint32_t prvTraceGetQueueNumber(void* handle) +{ + return (uint32_t)uxQueueGetQueueNumber(handle); +} +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) */ + +uint8_t prvTraceGetQueueType(void* handle) +{ + // This is either declared in header file in FreeRTOS 8 and later, or as extern above + return ucQueueGetQueueType(handle); +} + +/* Tasks */ +uint16_t prvTraceGetTaskNumberLow16(void* handle) +{ + return TRACE_GET_LOW16(uxTaskGetTaskNumber(handle)); +} + +uint16_t prvTraceGetTaskNumberHigh16(void* handle) +{ + return TRACE_GET_HIGH16(uxTaskGetTaskNumber(handle)); +} + +void prvTraceSetTaskNumberLow16(void* handle, uint16_t value) +{ + vTaskSetTaskNumber(handle, TRACE_SET_LOW16(uxTaskGetTaskNumber(handle), value)); +} + +void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value) +{ + vTaskSetTaskNumber(handle, TRACE_SET_HIGH16(uxTaskGetTaskNumber(handle), value)); +} + +uint16_t prvTraceGetQueueNumberLow16(void* handle) +{ + return TRACE_GET_LOW16(prvTraceGetQueueNumber(handle)); +} + +uint16_t prvTraceGetQueueNumberHigh16(void* handle) +{ + return TRACE_GET_HIGH16(prvTraceGetQueueNumber(handle)); +} + +void prvTraceSetQueueNumberLow16(void* handle, uint16_t value) +{ + vQueueSetQueueNumber(handle, TRACE_SET_LOW16(prvTraceGetQueueNumber(handle), value)); +} + +void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value) +{ + vQueueSetQueueNumber(handle, TRACE_SET_HIGH16(prvTraceGetQueueNumber(handle), value)); +} + +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) + +uint16_t prvTraceGetTimerNumberLow16(void* handle) +{ + return TRACE_GET_LOW16(uxTimerGetTimerNumber(handle)); +} + +uint16_t prvTraceGetTimerNumberHigh16(void* handle) +{ + return TRACE_GET_HIGH16(uxTimerGetTimerNumber(handle)); +} + +void prvTraceSetTimerNumberLow16(void* handle, uint16_t value) +{ + vTimerSetTimerNumber(handle, TRACE_SET_LOW16(uxTimerGetTimerNumber(handle), value)); +} + +void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value) +{ + vTimerSetTimerNumber(handle, TRACE_SET_HIGH16(uxTimerGetTimerNumber(handle), value)); +} +#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) + +uint16_t prvTraceGetEventGroupNumberLow16(void* handle) +{ + return TRACE_GET_LOW16(uxEventGroupGetNumber(handle)); +} + +uint16_t prvTraceGetEventGroupNumberHigh16(void* handle) +{ + return TRACE_GET_HIGH16(uxEventGroupGetNumber(handle)); +} + +void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value) +{ + vEventGroupSetNumber(handle, TRACE_SET_LOW16(uxEventGroupGetNumber(handle), value)); +} + +void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value) +{ + vEventGroupSetNumber(handle, TRACE_SET_HIGH16(uxEventGroupGetNumber(handle), value)); +} +#endif /* (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) + +uint16_t prvTraceGetStreamBufferNumberLow16(void* handle) +{ + return TRACE_GET_LOW16(uxStreamBufferGetStreamBufferNumber(handle)); +} + +uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle) +{ + return TRACE_GET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle)); +} + +void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value) +{ + vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_LOW16(uxStreamBufferGetStreamBufferNumber(handle), value)); +} + +void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value) +{ + vStreamBufferSetStreamBufferNumber(handle, TRACE_SET_HIGH16(uxStreamBufferGetStreamBufferNumber(handle), value)); +} +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +static void* pCurrentTCB = NULL; +#if (defined(configENABLE_BACKWARD_COMPATIBILITY) && configENABLE_BACKWARD_COMPATIBILITY == 0) +/* We're explicitly not using compatibility mode */ +static TaskHandle_t HandleTzCtrl = NULL; /* TzCtrl task TCB */ +#else +/* We're using compatibility mode, or we're running an old kernel */ +static xTaskHandle HandleTzCtrl = NULL; /* TzCtrl task TCB */ +#endif + +#if defined(configSUPPORT_STATIC_ALLOCATION) +#if (configSUPPORT_STATIC_ALLOCATION == 1) +static StackType_t stackTzCtrl[TRC_CFG_CTRL_TASK_STACK_SIZE]; +static StaticTask_t tcbTzCtrl; +#endif +#endif + +/* Monitored by TzCtrl task, that give warnings as User Events */ +extern volatile uint32_t NoRoomForSymbol; +extern volatile uint32_t NoRoomForObjectData; +extern volatile uint32_t LongestSymbolName; +extern volatile uint32_t MaxBytesTruncated; + +/* Keeps track of previous values, to only react on changes. */ +static uint32_t NoRoomForSymbol_last = 0; +static uint32_t NoRoomForObjectData_last = 0; +static uint32_t LongestSymbolName_last = 0; +static uint32_t MaxBytesTruncated_last = 0; + +/* User Event Channel for giving warnings regarding NoRoomForSymbol etc. */ +traceString trcWarningChannel; + +#define TRC_PORT_MALLOC(size) pvPortMalloc(size) + +TRC_STREAM_PORT_ALLOCATE_FIELDS() + +/* Called by TzCtrl task periodically (Normally every 100 ms) */ +static void prvCheckRecorderStatus(void); + +extern void prvTraceWarning(int errCode); + +/* The TzCtrl task - receives commands from Tracealyzer (start/stop) */ +static portTASK_FUNCTION( TzCtrl, pvParameters ); + +/******************************************************************************* + * vTraceEnable + * + * Function that enables the tracing and creates the control task. It will halt + * execution until a Start command has been received if haltUntilStart is true. + * + ******************************************************************************/ +void vTraceEnable(int startOption) +{ + int32_t bytes = 0; + int32_t status; + extern uint32_t RecorderEnabled; + TracealyzerCommandType msg; + + /* Only do this first time...*/ + if (HandleTzCtrl == NULL) + { + TRC_STREAM_PORT_INIT(); + + /* Note: Requires that TRC_CFG_INCLUDE_USER_EVENTS is 1. */ + trcWarningChannel = xTraceRegisterString("Warnings from Recorder"); + + /* Creates the TzCtrl task - receives trace commands (start, stop, ...) */ + #if defined(configSUPPORT_STATIC_ALLOCATION) && (configSUPPORT_STATIC_ALLOCATION == 1) + HandleTzCtrl = xTaskCreateStatic(TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, stackTzCtrl, &tcbTzCtrl); + #else + xTaskCreate( TzCtrl, STRING_CAST("TzCtrl"), TRC_CFG_CTRL_TASK_STACK_SIZE, NULL, TRC_CFG_CTRL_TASK_PRIORITY, &HandleTzCtrl ); + #endif + + if (HandleTzCtrl == NULL) + { + prvTraceError(PSF_ERROR_TZCTRLTASK_NOT_CREATED); + } + } + + if (startOption == TRC_START_AWAIT_HOST) + { + /* We keep trying to read commands until the recorder has been started */ + do + { + bytes = 0; + + status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes); + + if (status != 0) + { + prvTraceWarning(PSF_WARNING_STREAM_PORT_READ); + } + + if ((status == 0) && (bytes == sizeof(TracealyzerCommandType))) + { + if (prvIsValidCommand(&msg)) + { + if (msg.cmdCode == CMD_SET_ACTIVE && msg.param1 == 1) + { + /* On start, init and reset the timestamping */ + TRC_PORT_SPECIFIC_INIT(); + } + + prvProcessCommand(&msg); + } + } + } + while (RecorderEnabled == 0); + } + else if (startOption == TRC_START) + { + /* We start streaming directly - this assumes that the interface is ready! */ + TRC_PORT_SPECIFIC_INIT(); + + msg.cmdCode = CMD_SET_ACTIVE; + msg.param1 = 1; + prvProcessCommand(&msg); + } + else + { + /* On TRC_INIT */ + TRC_PORT_SPECIFIC_INIT(); + } +} + +/******************************************************************************* + * vTraceSetQueueName(void* object, const char* name) + * + * Parameter object: pointer to the Queue that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Queue objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetQueueName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* + * vTraceSetSemaphoreName(void* object, const char* name) + * + * Parameter object: pointer to the Semaphore that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Semaphore objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetSemaphoreName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* + * vTraceSetMutexName(void* object, const char* name) + * + * Parameter object: pointer to the Mutex that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Mutex objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetMutexName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* +* vTraceSetEventGroupName(void* object, const char* name) +* +* Parameter object: pointer to the vTraceSetEventGroupName that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for EventGroup objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetEventGroupName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* +* vTraceSetStreamBufferName(void* object, const char* name) +* +* Parameter object: pointer to the StreamBuffer that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for StreamBuffer objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetStreamBufferName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* +* vTraceSetMessageBufferName(void* object, const char* name) +* +* Parameter object: pointer to the MessageBuffer that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for MessageBuffer objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetMessageBufferName(void* object, const char* name) +{ + vTraceStoreKernelObjectName(object, name); +} + +/******************************************************************************* + * prvGetCurrentTaskHandle + * + * Function that returns the handle to the currently executing task. + * + ******************************************************************************/ +void* prvTraceGetCurrentTaskHandle(void) +{ + return xTaskGetCurrentTaskHandle(); +} + +/******************************************************************************* + * prvIsNewTCB + * + * Tells if this task is already executing, or if there has been a task-switch. + * Assumed to be called within a trace hook in kernel context. + ******************************************************************************/ +uint32_t prvIsNewTCB(void* pNewTCB) +{ + if (pCurrentTCB != pNewTCB) + { + pCurrentTCB = pNewTCB; + return 1; + } + return 0; +} + +/******************************************************************************* + * prvTraceIsSchedulerSuspended + * + * Returns true if the RTOS scheduler currently is disabled, thus preventing any + * task-switches from occurring. Only called from vTraceStoreISREnd. + ******************************************************************************/ +unsigned char prvTraceIsSchedulerSuspended(void) +{ + /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs, + INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in + FreeRTOSConfig.h for this function to be available. */ + + return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED; +} + + +/******************************************************************************* + * prvCheckRecorderStatus + * + * Called by TzCtrl task periodically (every 100 ms - seems reasonable). + * Checks a number of diagnostic variables and give warnings as user events, + * in most cases including a suggested solution. + ******************************************************************************/ +static void prvCheckRecorderStatus(void) +{ + if (NoRoomForSymbol > NoRoomForSymbol_last) + { + if (NoRoomForSymbol > 0) + { + prvTraceWarning(PSF_WARNING_SYMBOL_TABLE_SLOTS); + } + NoRoomForSymbol_last = NoRoomForSymbol; + } + + if (NoRoomForObjectData > NoRoomForObjectData_last) + { + if (NoRoomForObjectData > 0) + { + prvTraceWarning(PSF_WARNING_OBJECT_DATA_SLOTS); + } + NoRoomForObjectData_last = NoRoomForObjectData; + } + + if (LongestSymbolName > LongestSymbolName_last) + { + if (LongestSymbolName > TRC_CFG_SYMBOL_MAX_LENGTH) + { + prvTraceWarning(PSF_WARNING_SYMBOL_MAX_LENGTH); + } + LongestSymbolName_last = LongestSymbolName; + } + + if (MaxBytesTruncated > MaxBytesTruncated_last) + { + if (MaxBytesTruncated > 0) + { + prvTraceWarning(PSF_WARNING_STRING_TOO_LONG); + } + MaxBytesTruncated_last = MaxBytesTruncated; + } +} + +/******************************************************************************* + * TzCtrl + * + * Task for sending the trace data from the internal buffer to the stream + * interface (assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) and for + * receiving commands from Tracealyzer. Also does some diagnostics. + ******************************************************************************/ +static portTASK_FUNCTION( TzCtrl, pvParameters ) +{ + TracealyzerCommandType msg; + int32_t bytes = 0; + int32_t status = 0; + (void)pvParameters; + + while (1) + { + do + { + /* Listen for new commands */ + bytes = 0; + status = TRC_STREAM_PORT_READ_DATA(&msg, sizeof(TracealyzerCommandType), (int32_t*)&bytes); + + if (status != 0) + { + prvTraceWarning(PSF_WARNING_STREAM_PORT_READ); + } + + if ((status == 0) && (bytes == sizeof(TracealyzerCommandType))) + { + if (prvIsValidCommand(&msg)) + { + prvProcessCommand(&msg); /* Start or Stop currently... */ + } + } + +/* If the internal buffer is disabled, the COMMIT macro instead sends the data directly + from the "event functions" (using TRC_STREAM_PORT_WRITE_DATA). */ +#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + /* If there is a buffer page, this sends it to the streaming interface using TRC_STREAM_PORT_WRITE_DATA. */ + bytes = prvPagedEventBufferTransfer(); +#endif + + /* If there was data sent or received (bytes != 0), loop around and repeat, if there is more data to send or receive. + Otherwise, step out of this loop and sleep for a while. */ + + } while (bytes != 0); + + prvCheckRecorderStatus(); + + vTaskDelay(TRC_CFG_CTRL_TASK_DELAY); + } +} + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + +/* Internal flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ +int uiInEventGroupSetBitsFromISR = 0; + +/****************************************************************************** + * TraceQueueClassTable + * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_). + * Has one entry for each QueueType, gives TRACE_CLASS ID. + ******************************************************************************/ +traceObjectClass TraceQueueClassTable[5] = { + TRACE_CLASS_QUEUE, + TRACE_CLASS_MUTEX, + TRACE_CLASS_SEMAPHORE, + TRACE_CLASS_SEMAPHORE, + TRACE_CLASS_MUTEX +}; + +/******************************************************************************* + * vTraceSetQueueName(void* object, const char* name) + * + * Parameter object: pointer to the Queue that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Queue objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetQueueName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_QUEUE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); +} + +/******************************************************************************* + * vTraceSetSemaphoreName(void* object, const char* name) + * + * Parameter object: pointer to the Semaphore that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Semaphore objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetSemaphoreName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_SEMAPHORE, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); +} + +/******************************************************************************* + * vTraceSetMutexName(void* object, const char* name) + * + * Parameter object: pointer to the Mutex that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Semaphore objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetMutexName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_MUTEX, TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); +} + +#if (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +/******************************************************************************* +* vTraceSetEventGroupName(void* object, const char* name) +* +* Parameter object: pointer to the EventGroup that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for EventGroup objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetEventGroupName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_EVENTGROUP, TRACE_GET_OBJECT_NUMBER(EVENTGROUP, object), name); +} +#endif /* (TRC_CFG_INCLUDE_TIMER_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +/******************************************************************************* +* vTraceSetStreamBufferName(void* object, const char* name) +* +* Parameter object: pointer to the StreamBuffer that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for StreamBuffer objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetStreamBufferName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_STREAMBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name); +} + +/******************************************************************************* +* vTraceSetMessageBufferName(void* object, const char* name) +* +* Parameter object: pointer to the MessageBuffer that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for MessageBuffer objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetMessageBufferName(void* object, const char* name) +{ + prvTraceSetObjectName(TRACE_CLASS_MESSAGEBUFFER, TRACE_GET_OBJECT_NUMBER(STREAMBUFFER, object), name); +} +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +void* prvTraceGetCurrentTaskHandle() +{ + return xTaskGetCurrentTaskHandle(); +} + +/* Initialization of the object property table */ +void vTraceInitObjectPropertyTable() +{ + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectClasses = TRACE_NCLASSES; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[0] = TRC_CFG_NQUEUE; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[1] = TRC_CFG_NSEMAPHORE; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[2] = TRC_CFG_NMUTEX; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[3] = TRC_CFG_NTASK; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[4] = TRC_CFG_NISR; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[5] = TRC_CFG_NTIMER; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[6] = TRC_CFG_NEVENTGROUP; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[7] = TRC_CFG_NSTREAMBUFFER; + RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[8] = TRC_CFG_NMESSAGEBUFFER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[0] = TRC_CFG_NAME_LEN_QUEUE; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[1] = TRC_CFG_NAME_LEN_SEMAPHORE; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[2] = TRC_CFG_NAME_LEN_MUTEX; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[3] = TRC_CFG_NAME_LEN_TASK; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[4] = TRC_CFG_NAME_LEN_ISR; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[5] = TRC_CFG_NAME_LEN_TIMER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[6] = TRC_CFG_NAME_LEN_EVENTGROUP; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[7] = TRC_CFG_NAME_LEN_STREAMBUFFER; + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[8] = TRC_CFG_NAME_LEN_MESSAGEBUFFER; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[0] = PropertyTableSizeQueue; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[1] = PropertyTableSizeSemaphore; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[2] = PropertyTableSizeMutex; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[3] = PropertyTableSizeTask; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[4] = PropertyTableSizeISR; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[5] = PropertyTableSizeTimer; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[6] = PropertyTableSizeEventGroup; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[7] = PropertyTableSizeStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[8] = PropertyTableSizeMessageBuffer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[0] = StartIndexQueue; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[1] = StartIndexSemaphore; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[2] = StartIndexMutex; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[3] = StartIndexTask; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[4] = StartIndexISR; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[5] = StartIndexTimer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[6] = StartIndexEventGroup; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[7] = StartIndexStreamBuffer; + RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[8] = StartIndexMessageBuffer; + RecorderDataPtr->ObjectPropertyTable.ObjectPropertyTableSizeInBytes = TRACE_OBJECT_TABLE_SIZE; +} + +/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */ +void vTraceInitObjectHandleStack() +{ + objectHandleStacks.indexOfNextAvailableHandle[0] = objectHandleStacks.lowestIndexOfClass[0] = 0; + objectHandleStacks.indexOfNextAvailableHandle[1] = objectHandleStacks.lowestIndexOfClass[1] = TRC_CFG_NQUEUE; + objectHandleStacks.indexOfNextAvailableHandle[2] = objectHandleStacks.lowestIndexOfClass[2] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE; + objectHandleStacks.indexOfNextAvailableHandle[3] = objectHandleStacks.lowestIndexOfClass[3] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX; + objectHandleStacks.indexOfNextAvailableHandle[4] = objectHandleStacks.lowestIndexOfClass[4] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK; + objectHandleStacks.indexOfNextAvailableHandle[5] = objectHandleStacks.lowestIndexOfClass[5] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR; + objectHandleStacks.indexOfNextAvailableHandle[6] = objectHandleStacks.lowestIndexOfClass[6] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER; + objectHandleStacks.indexOfNextAvailableHandle[7] = objectHandleStacks.lowestIndexOfClass[7] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP; + objectHandleStacks.indexOfNextAvailableHandle[8] = objectHandleStacks.lowestIndexOfClass[8] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP + TRC_CFG_NSTREAMBUFFER; + + objectHandleStacks.highestIndexOfClass[0] = TRC_CFG_NQUEUE - 1; + objectHandleStacks.highestIndexOfClass[1] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE - 1; + objectHandleStacks.highestIndexOfClass[2] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX - 1; + objectHandleStacks.highestIndexOfClass[3] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK - 1; + objectHandleStacks.highestIndexOfClass[4] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR - 1; + objectHandleStacks.highestIndexOfClass[5] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER - 1; + objectHandleStacks.highestIndexOfClass[6] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP - 1; + objectHandleStacks.highestIndexOfClass[7] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP + TRC_CFG_NSTREAMBUFFER - 1; + objectHandleStacks.highestIndexOfClass[8] = TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP + TRC_CFG_NSTREAMBUFFER + TRC_CFG_NMESSAGEBUFFER - 1; +} + +/* Returns the "Not enough handles" error message for this object class */ +const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass) +{ + switch(objectclass) + { + case TRACE_CLASS_TASK: + return "Not enough TASK handles - increase TRC_CFG_NTASK in trcSnapshotConfig.h"; + case TRACE_CLASS_ISR: + return "Not enough ISR handles - increase TRC_CFG_NISR in trcSnapshotConfig.h"; + case TRACE_CLASS_SEMAPHORE: + return "Not enough SEMAPHORE handles - increase TRC_CFG_NSEMAPHORE in trcSnapshotConfig.h"; + case TRACE_CLASS_MUTEX: + return "Not enough MUTEX handles - increase TRC_CFG_NMUTEX in trcSnapshotConfig.h"; + case TRACE_CLASS_QUEUE: + return "Not enough QUEUE handles - increase TRC_CFG_NQUEUE in trcSnapshotConfig.h"; + case TRACE_CLASS_TIMER: + return "Not enough TIMER handles - increase TRC_CFG_NTIMER in trcSnapshotConfig.h"; + case TRACE_CLASS_EVENTGROUP: + return "Not enough EVENTGROUP handles - increase TRC_CFG_NEVENTGROUP in trcSnapshotConfig.h"; + case TRACE_CLASS_STREAMBUFFER: + return "Not enough STREAMBUFFER handles - increase TRC_CFG_NSTREAMBUFFER in trcSnapshotConfig.h"; + case TRACE_CLASS_MESSAGEBUFFER: + return "Not enough MESSAGEBUFFER handles - increase TRC_CFG_NMESSAGEBUFFER in trcSnapshotConfig.h"; + default: + return "pszTraceGetErrorHandles: Invalid objectclass!"; + } +} + +/******************************************************************************* + * prvTraceIsSchedulerSuspended + * + * Returns true if the RTOS scheduler currently is disabled, thus preventing any + * task-switches from occurring. Only called from vTraceStoreISREnd. + ******************************************************************************/ +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) +unsigned char prvTraceIsSchedulerSuspended(void) +{ + /* Assumed to be available in FreeRTOS. According to the FreeRTOS docs, + INCLUDE_xTaskGetSchedulerState or configUSE_TIMERS must be set to 1 in + FreeRTOSConfig.h for this function to be available. */ + + return xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED; +} +#endif + +#endif /* Snapshot mode */ + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ +#endif /* configUSE_PERCEPIO_TRACE_HOOKS */ /* << EST: FreeRTOS using Percepio Trace */ + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.h new file mode 100644 index 0000000..f3fc3b6 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcKernelPort.h @@ -0,0 +1,2515 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * FreeRTOS-specific definitions needed by the trace recorder + * + * + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_KERNEL_PORT_H +#define TRC_KERNEL_PORT_H + +#include "FreeRTOS.h" /* Defines configUSE_TRACE_FACILITY */ +#include "trcPortDefines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define TRC_USE_TRACEALYZER_RECORDER configUSE_TRACE_FACILITY + +/*** FreeRTOS version codes **************************************************/ +#define FREERTOS_VERSION_NOT_SET 0 +#define TRC_FREERTOS_VERSION_7_3 1 /* v7.3 is earliest supported.*/ +#define TRC_FREERTOS_VERSION_7_4 2 +#define TRC_FREERTOS_VERSION_7_5_OR_7_6 3 +#define TRC_FREERTOS_VERSION_8_X 4 /* Any v8.x.x*/ +#define TRC_FREERTOS_VERSION_9_0_0 5 +#define TRC_FREERTOS_VERSION_9_0_1 6 +#define TRC_FREERTOS_VERSION_9_0_2 7 +#define TRC_FREERTOS_VERSION_10_0_0 8 /* If using FreeRTOS v10.0.0 or later version */ + +#define TRC_FREERTOS_VERSION_9_X 42 /* Not allowed anymore */ + +#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_X) +/* This setting for TRC_CFG_FREERTOS_VERSION is no longer allowed as v9.0.1 needs special handling. */ +#error "Please specify your exact FreeRTOS version in trcConfig.h, from the options listed above." +#endif + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define prvGetStreamBufferType(x) ((( StreamBuffer_t * )x )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER) +#else +#define prvGetStreamBufferType(x) 0 +#endif + +/* Added mainly for our internal testing. This makes it easier to create test applications that + runs on multiple FreeRTOS versions. */ +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_8_X) + /* FreeRTOS v7.0 and later */ + #define STRING_CAST(x) ( (signed char*) x ) + #define TickType portTickType +#else + /* FreeRTOS v8.0 and later */ + #define STRING_CAST(x) x + #define TickType TickType_t +#endif + +#if (defined(TRC_USE_TRACEALYZER_RECORDER)) && (TRC_USE_TRACEALYZER_RECORDER == 1) + +/******************************************************************************* + * INCLUDE_xTaskGetCurrentTaskHandle must be set to 1 for tracing to work properly + ******************************************************************************/ +#undef INCLUDE_xTaskGetCurrentTaskHandle +#define INCLUDE_xTaskGetCurrentTaskHandle 1 + +#ifndef TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS +#define TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS 0 +#endif + +#ifndef TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS +#define TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS 0 +#endif + +#ifndef TRC_CFG_INCLUDE_TIMER_EVENTS +#define TRC_CFG_INCLUDE_TIMER_EVENTS 0 +#endif + +/******************************************************************************* + * vTraceSetQueueName(void* object, const char* name) + * + * Parameter object: pointer to the Queue that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Queue objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetQueueName(void* object, const char* name); + +/******************************************************************************* + * vTraceSetSemaphoreName(void* object, const char* name) + * + * Parameter object: pointer to the Semaphore that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Semaphore objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetSemaphoreName(void* object, const char* name); + +/******************************************************************************* + * vTraceSetMutexName(void* object, const char* name) + * + * Parameter object: pointer to the Mutex that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for Semaphore objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetMutexName(void* object, const char* name); + +/******************************************************************************* +* vTraceSetEventGroupName(void* object, const char* name) +* +* Parameter object: pointer to the EventGroup that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for EventGroup objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetEventGroupName(void* object, const char* name); + +/******************************************************************************* +* vTraceSetStreamBufferName(void* object, const char* name) +* +* Parameter object: pointer to the StreamBuffer that shall be named +* Parameter name: the name to set (const string literal) +* +* Sets a name for StreamBuffer objects for display in Tracealyzer. +******************************************************************************/ +void vTraceSetStreamBufferName(void* object, const char* name); + +/******************************************************************************* + * vTraceSetMessageBufferName(void* object, const char* name) + * + * Parameter object: pointer to the MessageBuffer that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for MessageBuffer objects for display in Tracealyzer. + ******************************************************************************/ +void vTraceSetMessageBufferName(void* object, const char* name); + +/******************************************************************************* + * Note: Setting names for event groups is difficult to support, this has been + * excluded intentionally. This since we don't know if event_groups.c is + * included in the build, so referencing it from the recorder may cause errors. + ******************************************************************************/ + +/* Gives the currently executing task (wrapper for RTOS-specific function) */ +void* prvTraceGetCurrentTaskHandle(void); + +#if (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)) +/* Tells if the scheduler currently is suspended (task-switches can't occur) */ +unsigned char prvTraceIsSchedulerSuspended(void); + +/******************************************************************************* + * INCLUDE_xTaskGetSchedulerState must be set to 1 for tracing to work properly + ******************************************************************************/ +#undef INCLUDE_xTaskGetSchedulerState +#define INCLUDE_xTaskGetSchedulerState 1 + +#endif /* (((TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) && (TRC_CFG_INCLUDE_ISR_TRACING == 1)) || (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)) */ + +#define TRACE_KERNEL_VERSION 0x1AA1 +#define TRACE_TICK_RATE_HZ configTICK_RATE_HZ /* Defined in "FreeRTOS.h" */ +#define TRACE_CPU_CLOCK_HZ configCPU_CLOCK_HZ /* Defined in "FreeRTOSConfig.h" */ +#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle() + +#define TRACE_GET_OS_TICKS() (uiTraceTickCount) /* Streaming only */ + +/* If using dynamic allocation of snapshot trace buffer... */ +#define TRACE_MALLOC(size) pvPortMalloc(size) + +#ifdef configUSE_TIMERS +#if (configUSE_TIMERS == 1) +#undef INCLUDE_xTimerGetTimerDaemonTaskHandle +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#endif /* configUSE_TIMERS == 1*/ +#endif /* configUSE_TIMERS */ + +/* For ARM Cortex-M devices - assumes the ARM CMSIS API is available */ +#if (defined (__CORTEX_M)) + #define TRACE_ALLOC_CRITICAL_SECTION() uint32_t __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = __get_PRIMASK(); __set_PRIMASK(1);} /* PRIMASK disables ALL interrupts - allows for tracing in any ISR */ + #define TRACE_EXIT_CRITICAL_SECTION() {__set_PRIMASK(__irq_status);} +#endif + +#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_CORTEX_A9) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Renesas_RX600) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32) || (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Altera_NiosII)) + #define TRACE_ALLOC_CRITICAL_SECTION() int __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();} + #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);} +#endif + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32) + /* In the Win32 port, there are no real interrupts, so we can use the normal critical sections */ + #define TRACE_ALLOC_CRITICAL_SECTION() + #define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL() + #define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL() +#endif + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_PROCESSOR_EXPERT) /* << EST */ + #define TRACE_ALLOC_CRITICAL_SECTION() + #define TRACE_ENTER_CRITICAL_SECTION() portENTER_CRITICAL() + #define TRACE_EXIT_CRITICAL_SECTION() portEXIT_CRITICAL() +#endif + + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_POWERPC_Z4) +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) + /* FreeRTOS v8.0 or later */ + #define TRACE_ALLOC_CRITICAL_SECTION() UBaseType_t __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();} + #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);} +#else + /* FreeRTOS v7.x */ + #define TRACE_ALLOC_CRITICAL_SECTION() unsigned portBASE_TYPE __irq_status; + #define TRACE_ENTER_CRITICAL_SECTION() {__irq_status = portSET_INTERRUPT_MASK_FROM_ISR();} + #define TRACE_EXIT_CRITICAL_SECTION() {portCLEAR_INTERRUPT_MASK_FROM_ISR(__irq_status);} +#endif +#endif + +#ifndef TRACE_ENTER_CRITICAL_SECTION + #error "This hardware port has no definition for critical sections! See http://percepio.com/2014/10/27/how-to-define-critical-sections-for-the-recorder/" +#endif + + +#if (TRC_CFG_FREERTOS_VERSION == TRC_FREERTOS_VERSION_9_0_1) + /****************************************************************************** + * Fix for FreeRTOS v9.0.1 to correctly identify xQueuePeek events. + * + * In FreeRTOS v9.0.1, the below trace hooks are incorrectly used from three + * different functions. This as the earlier function xQueueGenericReceive + * has been replaced by xQueuePeek, xQueueSemaphoreTake and xQueueReceive. + * + * xQueueGenericReceive had a parameter "xJustPeeking", used by the trace hooks + * to tell between xQueuePeek events and others. This is no longer present, so + * we need another way to correctly identify peek events. Since all three + * functions call the same trace macros, the context of these macro is unknown. + * + * We therefore check the __LINE__ macro inside of the trace macros. This gives + * the line number of queue.c, where the macros are used. This can be used to + * tell if the context is xQueuePeek or another function. + * __LINE__ is a standard compiler feature since ancient times, so it should + * work on all common compilers. + * + * This might seem as a quite brittle and unusual solution, but works in this + * particular case and is only for FreeRTOS v9.0.1. + * Future versions of FreeRTOS should not need this fix, as we have submitted + * a correction of queue.c with individual trace macros for each function. + ******************************************************************************/ +#define isQueueReceiveHookActuallyPeek (__LINE__ > 1674) /* Half way between the closes trace points */ + +#elif (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_9_0_0) +#define isQueueReceiveHookActuallyPeek xJustPeeking + +#elif (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) +#define isQueueReceiveHookActuallyPeek (__LINE__ < 0) /* instead of pdFALSE to fix a warning of "constant condition" */ + +#endif + +extern uint16_t CurrentFilterMask; + +extern uint16_t CurrentFilterGroup; + +uint8_t prvTraceGetQueueType(void* handle); + +uint16_t prvTraceGetTaskNumberLow16(void* handle); +uint16_t prvTraceGetTaskNumberHigh16(void* handle); +void prvTraceSetTaskNumberLow16(void* handle, uint16_t value); +void prvTraceSetTaskNumberHigh16(void* handle, uint16_t value); + +uint16_t prvTraceGetQueueNumberLow16(void* handle); +uint16_t prvTraceGetQueueNumberHigh16(void* handle); +void prvTraceSetQueueNumberLow16(void* handle, uint16_t value); +void prvTraceSetQueueNumberHigh16(void* handle, uint16_t value); + +uint16_t prvTraceGetTimerNumberLow16(void* handle); +uint16_t prvTraceGetTimerNumberHigh16(void* handle); +void prvTraceSetTimerNumberLow16(void* handle, uint16_t value); +void prvTraceSetTimerNumberHigh16(void* handle, uint16_t value); + +uint16_t prvTraceGetEventGroupNumberLow16(void* handle); +uint16_t prvTraceGetEventGroupNumberHigh16(void* handle); +void prvTraceSetEventGroupNumberLow16(void* handle, uint16_t value); +void prvTraceSetEventGroupNumberHigh16(void* handle, uint16_t value); + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +uint16_t prvTraceGetStreamBufferNumberLow16(void* handle); +uint16_t prvTraceGetStreamBufferNumberHigh16(void* handle); +void prvTraceSetStreamBufferNumberLow16(void* handle, uint16_t value); +void prvTraceSetStreamBufferNumberHigh16(void* handle, uint16_t value); +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#define TRACE_GET_TASK_FILTER(pxTask) prvTraceGetTaskNumberHigh16((void*)pxTask) +#define TRACE_SET_TASK_FILTER(pxTask, group) prvTraceSetTaskNumberHigh16((void*)pxTask, group) + +#define TRACE_GET_QUEUE_FILTER(pxObject) prvTraceGetQueueNumberHigh16((void*)pxObject) +#define TRACE_SET_QUEUE_FILTER(pxObject, group) prvTraceSetQueueNumberHigh16((void*)pxObject, group) + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_EVENTGROUP_FILTER(pxObject) prvTraceGetEventGroupNumberHigh16((void*)pxObject) +#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) prvTraceSetEventGroupNumberHigh16((void*)pxObject, group) +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +/* FreeRTOS versions before v10.0 does not support filtering for event groups */ +#define TRACE_GET_EVENTGROUP_FILTER(pxObject) 1 +#define TRACE_SET_EVENTGROUP_FILTER(pxObject, group) +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_TIMER_FILTER(pxObject) prvTraceGetTimerNumberHigh16((void*)pxObject) +#define TRACE_SET_TIMER_FILTER(pxObject, group) prvTraceSetTimerNumberHigh16((void*)pxObject, group) +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +/* FreeRTOS versions before v10.0 does not support filtering for timers */ +#define TRACE_GET_TIMER_FILTER(pxObject) 1 +#define TRACE_SET_TIMER_FILTER(pxObject, group) +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#define TRACE_GET_STREAMBUFFER_FILTER(pxObject) prvTraceGetStreamBufferNumberHigh16((void*)pxObject) +#define TRACE_SET_STREAMBUFFER_FILTER(pxObject, group) prvTraceSetStreamBufferNumberHigh16((void*)pxObject, group) + +#define TRACE_GET_OBJECT_FILTER(CLASS, pxObject) TRACE_GET_##CLASS##_FILTER(pxObject) +#define TRACE_SET_OBJECT_FILTER(CLASS, pxObject, group) TRACE_SET_##CLASS##_FILTER(pxObject, group) + +/******************************************************************************/ +/*** Definitions for Snapshot mode ********************************************/ +/******************************************************************************/ +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + +/*** The object classes *******************************************************/ + +#define TRACE_NCLASSES 9 +#define TRACE_CLASS_QUEUE ((traceObjectClass)0) +#define TRACE_CLASS_SEMAPHORE ((traceObjectClass)1) +#define TRACE_CLASS_MUTEX ((traceObjectClass)2) +#define TRACE_CLASS_TASK ((traceObjectClass)3) +#define TRACE_CLASS_ISR ((traceObjectClass)4) +#define TRACE_CLASS_TIMER ((traceObjectClass)5) +#define TRACE_CLASS_EVENTGROUP ((traceObjectClass)6) +#define TRACE_CLASS_STREAMBUFFER ((traceObjectClass)7) +#define TRACE_CLASS_MESSAGEBUFFER ((traceObjectClass)8) + +/*** Definitions for Object Table ********************************************/ +#define TRACE_KERNEL_OBJECT_COUNT (TRC_CFG_NQUEUE + TRC_CFG_NSEMAPHORE + TRC_CFG_NMUTEX + TRC_CFG_NTASK + TRC_CFG_NISR + TRC_CFG_NTIMER + TRC_CFG_NEVENTGROUP + TRC_CFG_NSTREAMBUFFER + TRC_CFG_NMESSAGEBUFFER) + +/* Queue properties (except name): current number of message in queue */ +#define PropertyTableSizeQueue (TRC_CFG_NAME_LEN_QUEUE + 1) + +/* Semaphore properties (except name): state (signaled = 1, cleared = 0) */ +#define PropertyTableSizeSemaphore (TRC_CFG_NAME_LEN_SEMAPHORE + 1) + +/* Mutex properties (except name): owner (task handle, 0 = free) */ +#define PropertyTableSizeMutex (TRC_CFG_NAME_LEN_MUTEX + 1) + +/* Task properties (except name): Byte 0: Current priority + Byte 1: state (if already active) + Byte 2: legacy, not used + Byte 3: legacy, not used */ +#define PropertyTableSizeTask (TRC_CFG_NAME_LEN_TASK + 4) + +/* ISR properties: Byte 0: priority + Byte 1: state (if already active) */ +#define PropertyTableSizeISR (TRC_CFG_NAME_LEN_ISR + 2) + +/* TRC_CFG_NTIMER properties: Byte 0: state (unused for now) */ +#define PropertyTableSizeTimer (TRC_CFG_NAME_LEN_TIMER + 1) + +/* TRC_CFG_NEVENTGROUP properties: Byte 0-3: state (unused for now)*/ +#define PropertyTableSizeEventGroup (TRC_CFG_NAME_LEN_EVENTGROUP + 4) + +/* TRC_CFG_NSTREAMBUFFER properties: Byte 0-3: state (unused for now)*/ +#define PropertyTableSizeStreamBuffer (TRC_CFG_NAME_LEN_STREAMBUFFER + 4) + +/* TRC_CFG_NMESSAGEBUFFER properties: Byte 0-3: state (unused for now)*/ +#define PropertyTableSizeMessageBuffer (TRC_CFG_NAME_LEN_MESSAGEBUFFER + 4) + + +/* The layout of the byte array representing the Object Property Table */ +#define StartIndexQueue 0 +#define StartIndexSemaphore StartIndexQueue + TRC_CFG_NQUEUE * PropertyTableSizeQueue +#define StartIndexMutex StartIndexSemaphore + TRC_CFG_NSEMAPHORE * PropertyTableSizeSemaphore +#define StartIndexTask StartIndexMutex + TRC_CFG_NMUTEX * PropertyTableSizeMutex +#define StartIndexISR StartIndexTask + TRC_CFG_NTASK * PropertyTableSizeTask +#define StartIndexTimer StartIndexISR + TRC_CFG_NISR * PropertyTableSizeISR +#define StartIndexEventGroup StartIndexTimer + TRC_CFG_NTIMER * PropertyTableSizeTimer +#define StartIndexStreamBuffer StartIndexEventGroup + TRC_CFG_NEVENTGROUP * PropertyTableSizeEventGroup +#define StartIndexMessageBuffer StartIndexStreamBuffer + TRC_CFG_NSTREAMBUFFER * PropertyTableSizeStreamBuffer + +/* Number of bytes used by the object table */ +#define TRACE_OBJECT_TABLE_SIZE StartIndexMessageBuffer + TRC_CFG_NMESSAGEBUFFER * PropertyTableSizeMessageBuffer + +/* Flag to tell the context of tracePEND_FUNC_CALL_FROM_ISR */ +extern int uiInEventGroupSetBitsFromISR; + +/* Initialization of the object property table */ +void vTraceInitObjectPropertyTable(void); + +/* Initialization of the handle mechanism, see e.g, prvTraceGetObjectHandle */ +void vTraceInitObjectHandleStack(void); + +/* Returns the "Not enough handles" error message for the specified object class */ +const char* pszTraceGetErrorNotEnoughHandles(traceObjectClass objectclass); + +void* prvTraceGetCurrentTaskHandle(void); + +/****************************************************************************** + * TraceQueueClassTable + * Translates a FreeRTOS QueueType into trace objects classes (TRACE_CLASS_). + * Has one entry for each QueueType, gives TRACE_CLASS ID. + ******************************************************************************/ +extern traceObjectClass TraceQueueClassTable[5]; + + +/*** Event codes for snapshot mode - must match Tracealyzer config files ******/ + +#define NULL_EVENT (0x00UL) + +/******************************************************************************* + * EVENTGROUP_DIV + * + * Miscellaneous events. + ******************************************************************************/ +#define EVENTGROUP_DIV (NULL_EVENT + 1UL) /*0x01*/ +#define DIV_XPS (EVENTGROUP_DIV + 0UL) /*0x01*/ +#define DIV_TASK_READY (EVENTGROUP_DIV + 1UL) /*0x02*/ +#define DIV_NEW_TIME (EVENTGROUP_DIV + 2UL) /*0x03*/ + +/******************************************************************************* + * EVENTGROUP_TS + * + * Events for storing task-switches and interrupts. The RESUME events are + * generated if the task/interrupt is already marked active. + ******************************************************************************/ +#define EVENTGROUP_TS (EVENTGROUP_DIV + 3UL) /*0x04*/ +#define TS_ISR_BEGIN (EVENTGROUP_TS + 0UL) /*0x04*/ +#define TS_ISR_RESUME (EVENTGROUP_TS + 1UL) /*0x05*/ +#define TS_TASK_BEGIN (EVENTGROUP_TS + 2UL) /*0x06*/ +#define TS_TASK_RESUME (EVENTGROUP_TS + 3UL) /*0x07*/ + +/******************************************************************************* + * EVENTGROUP_OBJCLOSE_NAME + * + * About Close Events + * When an object is evicted from the object property table (object close), two + * internal events are stored (EVENTGROUP_OBJCLOSE_NAME and + * EVENTGROUP_OBJCLOSE_PROP), containing the handle-name mapping and object + * properties valid up to this point. + ******************************************************************************/ +#define EVENTGROUP_OBJCLOSE_NAME_SUCCESS (EVENTGROUP_TS + 4UL) /*0x08*/ + +/******************************************************************************* + * EVENTGROUP_OBJCLOSE_PROP + * + * The internal event carrying properties of deleted objects + * The handle and object class of the closed object is not stored in this event, + * but is assumed to be the same as in the preceding CLOSE event. Thus, these + * two events must be generated from within a critical section. + * When queues are closed, arg1 is the "state" property (i.e., number of + * buffered messages/signals). + * When actors are closed, arg1 is priority, arg2 is handle of the "instance + * finish" event, and arg3 is event code of the "instance finish" event. + * In this case, the lower three bits is the object class of the instance finish + * handle. The lower three bits are not used (always zero) when queues are + * closed since the queue type is given in the previous OBJCLOSE_NAME event. + ******************************************************************************/ +#define EVENTGROUP_OBJCLOSE_PROP_SUCCESS (EVENTGROUP_OBJCLOSE_NAME_SUCCESS + 8UL) /*0x10*/ + +/******************************************************************************* + * EVENTGROUP_CREATE + * + * The events in this group are used to log Kernel object creations. + * The lower three bits in the event code gives the object class, i.e., type of + * create operation (task, queue, semaphore, etc). + ******************************************************************************/ +#define EVENTGROUP_CREATE_OBJ_SUCCESS (EVENTGROUP_OBJCLOSE_PROP_SUCCESS + 8UL) /*0x18*/ + +/******************************************************************************* + * EVENTGROUP_SEND + * + * The events in this group are used to log Send/Give events on queues, + * semaphores and mutexes The lower three bits in the event code gives the + * object class, i.e., what type of object that is operated on (queue, semaphore + * or mutex). + ******************************************************************************/ +#define EVENTGROUP_SEND_SUCCESS (EVENTGROUP_CREATE_OBJ_SUCCESS + 8UL) /*0x20*/ + +/******************************************************************************* + * EVENTGROUP_RECEIVE + * + * The events in this group are used to log Receive/Take events on queues, + * semaphores and mutexes. The lower three bits in the event code gives the + * object class, i.e., what type of object that is operated on (queue, semaphore + * or mutex). + ******************************************************************************/ +#define EVENTGROUP_RECEIVE_SUCCESS (EVENTGROUP_SEND_SUCCESS + 8UL) /*0x28*/ + +/* Send/Give operations, from ISR */ +#define EVENTGROUP_SEND_FROM_ISR_SUCCESS \ + (EVENTGROUP_RECEIVE_SUCCESS + 8UL) /*0x30*/ + +/* Receive/Take operations, from ISR */ +#define EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS \ + (EVENTGROUP_SEND_FROM_ISR_SUCCESS + 8UL) /*0x38*/ + +/* "Failed" event type versions of above (timeout, failed allocation, etc) */ +#define EVENTGROUP_KSE_FAILED \ + (EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + 8UL) /*0x40*/ + +/* Failed create calls - memory allocation failed */ +#define EVENTGROUP_CREATE_OBJ_FAILED (EVENTGROUP_KSE_FAILED) /*0x40*/ + +/* Failed send/give - timeout! */ +#define EVENTGROUP_SEND_FAILED (EVENTGROUP_CREATE_OBJ_FAILED + 8UL) /*0x48*/ + +/* Failed receive/take - timeout! */ +#define EVENTGROUP_RECEIVE_FAILED (EVENTGROUP_SEND_FAILED + 8UL) /*0x50*/ + +/* Failed non-blocking send/give - queue full */ +#define EVENTGROUP_SEND_FROM_ISR_FAILED (EVENTGROUP_RECEIVE_FAILED + 8UL) /*0x58*/ + +/* Failed non-blocking receive/take - queue empty */ +#define EVENTGROUP_RECEIVE_FROM_ISR_FAILED \ + (EVENTGROUP_SEND_FROM_ISR_FAILED + 8UL) /*0x60*/ + +/* Events when blocking on receive/take */ +#define EVENTGROUP_RECEIVE_BLOCK \ + (EVENTGROUP_RECEIVE_FROM_ISR_FAILED + 8UL) /*0x68*/ + +/* Events when blocking on send/give */ +#define EVENTGROUP_SEND_BLOCK (EVENTGROUP_RECEIVE_BLOCK + 8UL) /*0x70*/ + +/* Events on queue peek (receive) */ +#define EVENTGROUP_PEEK_SUCCESS (EVENTGROUP_SEND_BLOCK + 8UL) /*0x78*/ + +/* Events on object delete (vTaskDelete or vQueueDelete) */ +#define EVENTGROUP_DELETE_OBJ_SUCCESS (EVENTGROUP_PEEK_SUCCESS + 8UL) /*0x80*/ + +/* Other events - object class is implied: TASK */ +#define EVENTGROUP_OTHERS (EVENTGROUP_DELETE_OBJ_SUCCESS + 8UL) /*0x88*/ +#define TASK_DELAY_UNTIL (EVENTGROUP_OTHERS + 0UL) /*0x88*/ +#define TASK_DELAY (EVENTGROUP_OTHERS + 1UL) /*0x89*/ +#define TASK_SUSPEND (EVENTGROUP_OTHERS + 2UL) /*0x8A*/ +#define TASK_RESUME (EVENTGROUP_OTHERS + 3UL) /*0x8B*/ +#define TASK_RESUME_FROM_ISR (EVENTGROUP_OTHERS + 4UL) /*0x8C*/ +#define TASK_PRIORITY_SET (EVENTGROUP_OTHERS + 5UL) /*0x8D*/ +#define TASK_PRIORITY_INHERIT (EVENTGROUP_OTHERS + 6UL) /*0x8E*/ +#define TASK_PRIORITY_DISINHERIT (EVENTGROUP_OTHERS + 7UL) /*0x8F*/ + +#define EVENTGROUP_MISC_PLACEHOLDER (EVENTGROUP_OTHERS + 8UL) /*0x90*/ +#define PEND_FUNC_CALL (EVENTGROUP_MISC_PLACEHOLDER+0UL) /*0x90*/ +#define PEND_FUNC_CALL_FROM_ISR (EVENTGROUP_MISC_PLACEHOLDER+1UL) /*0x91*/ +#define PEND_FUNC_CALL_FAILED (EVENTGROUP_MISC_PLACEHOLDER+2UL) /*0x92*/ +#define PEND_FUNC_CALL_FROM_ISR_FAILED (EVENTGROUP_MISC_PLACEHOLDER+3UL) /*0x93*/ +#define MEM_MALLOC_SIZE (EVENTGROUP_MISC_PLACEHOLDER+4UL) /*0x94*/ +#define MEM_MALLOC_ADDR (EVENTGROUP_MISC_PLACEHOLDER+5UL) /*0x95*/ +#define MEM_FREE_SIZE (EVENTGROUP_MISC_PLACEHOLDER+6UL) /*0x96*/ +#define MEM_FREE_ADDR (EVENTGROUP_MISC_PLACEHOLDER+7UL) /*0x97*/ + +/* User events */ +#define EVENTGROUP_USEREVENT (EVENTGROUP_MISC_PLACEHOLDER + 8UL) /*0x98*/ +#define USER_EVENT (EVENTGROUP_USEREVENT + 0UL) + +/* Allow for 0-15 arguments (the number of args is added to event code) */ +#define USER_EVENT_LAST (EVENTGROUP_USEREVENT + 15UL) /*0xA7*/ + +/******************************************************************************* + * XTS Event - eXtended TimeStamp events + * The timestamps used in the recorder are "differential timestamps" (DTS), i.e. + * the time since the last stored event. The DTS fields are either 1 or 2 bytes + * in the other events, depending on the bytes available in the event struct. + * If the time since the last event (the DTS) is larger than allowed for by + * the DTS field of the current event, an XTS event is inserted immediately + * before the original event. The XTS event contains up to 3 additional bytes + * of the DTS value - the higher bytes of the true DTS value. The lower 1-2 + * bytes are stored in the normal DTS field. + * There are two types of XTS events, XTS8 and XTS16. An XTS8 event is stored + * when there is only room for 1 byte (8 bit) DTS data in the original event, + * which means a limit of 0xFF (255UL). The XTS16 is used when the original event + * has a 16 bit DTS field and thereby can handle values up to 0xFFFF (65535UL). + * + * Using a very high frequency time base can result in many XTS events. + * Preferably, the time between two OS ticks should fit in 16 bits, i.e., + * at most 65535. If your time base has a higher frequency, you can define + * the TRACE + ******************************************************************************/ + +#define EVENTGROUP_SYS (EVENTGROUP_USEREVENT + 16UL) /*0xA8*/ +#define XTS8 (EVENTGROUP_SYS + 0UL) /*0xA8*/ +#define XTS16 (EVENTGROUP_SYS + 1UL) /*0xA9*/ +#define EVENT_BEING_WRITTEN (EVENTGROUP_SYS + 2UL) /*0xAA*/ +#define RESERVED_DUMMY_CODE (EVENTGROUP_SYS + 3UL) /*0xAB*/ +#define LOW_POWER_BEGIN (EVENTGROUP_SYS + 4UL) /*0xAC*/ +#define LOW_POWER_END (EVENTGROUP_SYS + 5UL) /*0xAD*/ +#define XID (EVENTGROUP_SYS + 6UL) /*0xAE*/ +#define XTS16L (EVENTGROUP_SYS + 7UL) /*0xAF*/ + +#define EVENTGROUP_TIMER (EVENTGROUP_SYS + 8UL) /*0xB0*/ +#define TIMER_CREATE (EVENTGROUP_TIMER + 0UL) /*0xB0*/ +#define TIMER_START (EVENTGROUP_TIMER + 1UL) /*0xB1*/ +#define TIMER_RST (EVENTGROUP_TIMER + 2UL) /*0xB2*/ +#define TIMER_STOP (EVENTGROUP_TIMER + 3UL) /*0xB3*/ +#define TIMER_CHANGE_PERIOD (EVENTGROUP_TIMER + 4UL) /*0xB4*/ +#define TIMER_DELETE_OBJ (EVENTGROUP_TIMER + 5UL) /*0xB5*/ +#define TIMER_START_FROM_ISR (EVENTGROUP_TIMER + 6UL) /*0xB6*/ +#define TIMER_RESET_FROM_ISR (EVENTGROUP_TIMER + 7UL) /*0xB7*/ +#define TIMER_STOP_FROM_ISR (EVENTGROUP_TIMER + 8UL) /*0xB8*/ + +#define TIMER_CREATE_FAILED (EVENTGROUP_TIMER + 9UL) /*0xB9*/ +#define TIMER_START_FAILED (EVENTGROUP_TIMER + 10UL) /*0xBA*/ +#define TIMER_RESET_FAILED (EVENTGROUP_TIMER + 11UL) /*0xBB*/ +#define TIMER_STOP_FAILED (EVENTGROUP_TIMER + 12UL) /*0xBC*/ +#define TIMER_CHANGE_PERIOD_FAILED (EVENTGROUP_TIMER + 13UL) /*0xBD*/ +#define TIMER_DELETE_FAILED (EVENTGROUP_TIMER + 14UL) /*0xBE*/ +#define TIMER_START_FROM_ISR_FAILED (EVENTGROUP_TIMER + 15UL) /*0xBF*/ +#define TIMER_RESET_FROM_ISR_FAILED (EVENTGROUP_TIMER + 16UL) /*0xC0*/ +#define TIMER_STOP_FROM_ISR_FAILED (EVENTGROUP_TIMER + 17UL) /*0xC1*/ + +#define EVENTGROUP_EG (EVENTGROUP_TIMER + 18UL) /*0xC2*/ +#define EVENT_GROUP_CREATE (EVENTGROUP_EG + 0UL) /*0xC2*/ +#define EVENT_GROUP_CREATE_FAILED (EVENTGROUP_EG + 1UL) /*0xC3*/ +#define EVENT_GROUP_SYNC_BLOCK (EVENTGROUP_EG + 2UL) /*0xC4*/ +#define EVENT_GROUP_SYNC_END (EVENTGROUP_EG + 3UL) /*0xC5*/ +#define EVENT_GROUP_WAIT_BITS_BLOCK (EVENTGROUP_EG + 4UL) /*0xC6*/ +#define EVENT_GROUP_WAIT_BITS_END (EVENTGROUP_EG + 5UL) /*0xC7*/ +#define EVENT_GROUP_CLEAR_BITS (EVENTGROUP_EG + 6UL) /*0xC8*/ +#define EVENT_GROUP_CLEAR_BITS_FROM_ISR (EVENTGROUP_EG + 7UL) /*0xC9*/ +#define EVENT_GROUP_SET_BITS (EVENTGROUP_EG + 8UL) /*0xCA*/ +#define EVENT_GROUP_DELETE_OBJ (EVENTGROUP_EG + 9UL) /*0xCB*/ +#define EVENT_GROUP_SYNC_END_FAILED (EVENTGROUP_EG + 10UL) /*0xCC*/ +#define EVENT_GROUP_WAIT_BITS_END_FAILED (EVENTGROUP_EG + 11UL) /*0xCD*/ +#define EVENT_GROUP_SET_BITS_FROM_ISR (EVENTGROUP_EG + 12UL) /*0xCE*/ +#define EVENT_GROUP_SET_BITS_FROM_ISR_FAILED (EVENTGROUP_EG + 13UL) /*0xCF*/ + +#define TASK_INSTANCE_FINISHED_NEXT_KSE (EVENTGROUP_EG + 14UL) /*0xD0*/ +#define TASK_INSTANCE_FINISHED_DIRECT (EVENTGROUP_EG + 15UL) /*0xD1*/ + +#define TRACE_TASK_NOTIFY_GROUP (EVENTGROUP_EG + 16UL) /*0xD2*/ +#define TRACE_TASK_NOTIFY (TRACE_TASK_NOTIFY_GROUP + 0UL) /*0xD2*/ +#define TRACE_TASK_NOTIFY_TAKE (TRACE_TASK_NOTIFY_GROUP + 1UL) /*0xD3*/ +#define TRACE_TASK_NOTIFY_TAKE_BLOCK (TRACE_TASK_NOTIFY_GROUP + 2UL) /*0xD4*/ +#define TRACE_TASK_NOTIFY_TAKE_FAILED (TRACE_TASK_NOTIFY_GROUP + 3UL) /*0xD5*/ +#define TRACE_TASK_NOTIFY_WAIT (TRACE_TASK_NOTIFY_GROUP + 4UL) /*0xD6*/ +#define TRACE_TASK_NOTIFY_WAIT_BLOCK (TRACE_TASK_NOTIFY_GROUP + 5UL) /*0xD7*/ +#define TRACE_TASK_NOTIFY_WAIT_FAILED (TRACE_TASK_NOTIFY_GROUP + 6UL) /*0xD8*/ +#define TRACE_TASK_NOTIFY_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 7UL) /*0xD9*/ +#define TRACE_TASK_NOTIFY_GIVE_FROM_ISR (TRACE_TASK_NOTIFY_GROUP + 8UL) /*0xDA*/ + +#define TIMER_EXPIRED (TRACE_TASK_NOTIFY_GROUP + 9UL) /* 0xDB */ + + /* Events on queue peek (receive) */ +#define EVENTGROUP_PEEK_BLOCK (TRACE_TASK_NOTIFY_GROUP + 10UL) /*0xDC*/ +/* peek block on queue: 0xDC */ +/* peek block on semaphore: 0xDD */ +/* peek block on mutex: 0xDE */ + +/* Events on queue peek (receive) */ +#define EVENTGROUP_PEEK_FAILED (EVENTGROUP_PEEK_BLOCK + 3UL) /*0xDF*/ +/* peek failed on queue: 0xDF */ +/* peek failed on semaphore: 0xE0 */ +/* peek failed on mutex: 0xE1 */ + +#define EVENTGROUP_STREAMBUFFER_DIV (EVENTGROUP_PEEK_FAILED + 3UL) /*0xE2*/ +#define TRACE_STREAMBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 0) /*0xE2*/ +#define TRACE_MESSAGEBUFFER_RESET (EVENTGROUP_STREAMBUFFER_DIV + 1UL) /*0xE3*/ +#define TRACE_STREAMBUFFER_OBJCLOSE_NAME_SUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 2UL) /*0xE4*/ +#define TRACE_MESSAGEBUFFER_OBJCLOSE_NAME_SUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 3UL) /*0xE5*/ +#define TRACE_STREAMBUFFER_OBJCLOSE_PROP_SUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 4UL) /*0xE6*/ +#define TRACE_MESSAGEBUFFER_OBJCLOSE_PROP_SUCCESS (EVENTGROUP_STREAMBUFFER_DIV + 5UL) /*0xE7*/ + +/* The following are using previously "lost" event codes */ +#define TRACE_STREAMBUFFER_CREATE_OBJ_SUCCESS (EVENTGROUP_CREATE_OBJ_SUCCESS + 4UL) /*0x1C*/ +#define TRACE_STREAMBUFFER_CREATE_OBJ_FAILED (EVENTGROUP_CREATE_OBJ_FAILED + 4UL) /*0x44*/ +#define TRACE_STREAMBUFFER_DELETE_OBJ_SUCCESS (EVENTGROUP_DELETE_OBJ_SUCCESS + 4UL) /*0x84*/ +#define TRACE_STREAMBUFFER_SEND_SUCCESS (EVENTGROUP_SEND_SUCCESS + 3UL) /*0x23*/ +#define TRACE_STREAMBUFFER_SEND_BLOCK (EVENTGROUP_SEND_BLOCK + 3UL) /*0x73*/ +#define TRACE_STREAMBUFFER_SEND_FAILED (EVENTGROUP_SEND_FAILED + 3UL) /*0x4B*/ +#define TRACE_STREAMBUFFER_RECEIVE_SUCCESS (EVENTGROUP_RECEIVE_SUCCESS + 3UL) /*0x2B*/ +#define TRACE_STREAMBUFFER_RECEIVE_BLOCK (EVENTGROUP_RECEIVE_BLOCK + 3UL) /*0x6B*/ +#define TRACE_STREAMBUFFER_RECEIVE_FAILED (EVENTGROUP_RECEIVE_FAILED + 3UL) /*0x53*/ +#define TRACE_STREAMBUFFER_SEND_FROM_ISR_SUCCESS (EVENTGROUP_SEND_FROM_ISR_SUCCESS + 3UL) /*0x33*/ +#define TRACE_STREAMBUFFER_SEND_FROM_ISR_FAILED (EVENTGROUP_SEND_FROM_ISR_FAILED + 3UL) /*0x5B*/ +#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_SUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + 3UL) /*0x3B*/ +#define TRACE_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED (EVENTGROUP_RECEIVE_FROM_ISR_FAILED + 3UL) /*0x63*/ + +/* The following are using previously "lost" event codes. These macros aren't even directly referenced, instead we do (equivalent STREAMBUFFER code) + 1. */ +#define TRACE_MESSAGEBUFFER_CREATE_OBJ_SUCCESS (EVENTGROUP_CREATE_OBJ_SUCCESS + 5UL) /*0x1D*/ +#define TRACE_MESSAGEBUFFER_CREATE_OBJ_FAILED (EVENTGROUP_CREATE_OBJ_FAILED + 5UL) /*0x45*/ +#define TRACE_MESSAGEBUFFER_DELETE_OBJ_SUCCESS (EVENTGROUP_DELETE_OBJ_SUCCESS + 5UL) /*0x85*/ +#define TRACE_MESSAGEBUFFER_SEND_SUCCESS (EVENTGROUP_SEND_SUCCESS + 4UL) /*0x24*/ +#define TRACE_MESSAGEBUFFER_SEND_BLOCK (EVENTGROUP_SEND_BLOCK + 4UL) /*0x74*/ +#define TRACE_MESSAGEBUFFER_SEND_FAILED (EVENTGROUP_SEND_FAILED + 4UL) /*0x4C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_SUCCESS (EVENTGROUP_RECEIVE_SUCCESS + 4UL) /*0x2C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_BLOCK (EVENTGROUP_RECEIVE_BLOCK + 4UL) /*0x6C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_FAILED (EVENTGROUP_RECEIVE_FAILED + 4UL) /*0x54*/ +#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_SUCCESS (EVENTGROUP_SEND_FROM_ISR_SUCCESS + 4UL) /*0x34*/ +#define TRACE_MESSAGEBUFFER_SEND_FROM_ISR_FAILED (EVENTGROUP_SEND_FROM_ISR_FAILED + 4UL) /*0x5C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_SUCCESS (EVENTGROUP_RECEIVE_FROM_ISR_SUCCESS + 4UL) /*0x3C*/ +#define TRACE_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED (EVENTGROUP_RECEIVE_FROM_ISR_FAILED + 4UL) /*0x64*/ + +/* LAST EVENT (0xE7) */ + +/**************************** +* MACROS TO GET TRACE CLASS * +****************************/ +#define TRACE_GET_TRACE_CLASS_FROM_TASK_CLASS(kernelClass) (TRACE_CLASS_TASK) +#define TRACE_GET_TRACE_CLASS_FROM_TASK_OBJECT(pxObject) (TRACE_CLASS_TASK) + +#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(kernelClass) TraceQueueClassTable[kernelClass] +#define TRACE_GET_TRACE_CLASS_FROM_QUEUE_OBJECT(pxObject) TRACE_GET_TRACE_CLASS_FROM_QUEUE_CLASS(prvTraceGetQueueType(pxObject)) + +#define TRACE_GET_TRACE_CLASS_FROM_TIMER_CLASS(kernelClass) (TRACE_CLASS_TIMER) +#define TRACE_GET_TRACE_CLASS_FROM_TIMER_OBJECT(pxObject) (TRACE_CLASS_TIMER) + +#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_CLASS(kernelClass) (TRACE_CLASS_EVENTGROUP) +#define TRACE_GET_TRACE_CLASS_FROM_EVENTGROUP_OBJECT(pxObject) (TRACE_CLASS_EVENTGROUP) + +/* TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS can only be accessed with a parameter indicating if it is a MessageBuffer */ +#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_CLASS(xIsMessageBuffer) (xIsMessageBuffer == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) +#define TRACE_GET_TRACE_CLASS_FROM_STREAMBUFFER_OBJECT(pxObject) (prvGetStreamBufferType(pxObject) == 1 ? TRACE_CLASS_MESSAGEBUFFER : TRACE_CLASS_STREAMBUFFER) + +/* Generic versions */ +#define TRACE_GET_CLASS_TRACE_CLASS(CLASS, kernelClass) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_CLASS(kernelClass) +#define TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject) TRACE_GET_TRACE_CLASS_FROM_##CLASS##_OBJECT(pxObject) + +/****************************** +* MACROS TO GET OBJECT NUMBER * +******************************/ +#define TRACE_GET_TASK_NUMBER(pxTCB) (traceHandle)(prvTraceGetTaskNumberLow16(pxTCB)) +#define TRACE_SET_TASK_NUMBER(pxTCB) prvTraceSetTaskNumberLow16(pxTCB, prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TASK, pxTCB))); + +#define TRACE_GET_QUEUE_NUMBER(queue) ( ( traceHandle ) prvTraceGetQueueNumberLow16(queue) ) +#define TRACE_SET_QUEUE_NUMBER(queue) prvTraceSetQueueNumberLow16(queue, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, queue))); + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) prvTraceGetTimerNumberLow16(tmr) ) +#define TRACE_SET_TIMER_NUMBER(tmr) prvTraceSetTimerNumberLow16(tmr, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr))); +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +#define TRACE_GET_TIMER_NUMBER(tmr) ( ( traceHandle ) ((Timer_t*)tmr)->uxTimerNumber ) +#define TRACE_SET_TIMER_NUMBER(tmr) ((Timer_t*)tmr)->uxTimerNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr)); +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) +#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) prvTraceGetEventGroupNumberLow16(eg) ) +#define TRACE_SET_EVENTGROUP_NUMBER(eg) prvTraceSetEventGroupNumberLow16(eg, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg))); +#else /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ +#define TRACE_GET_EVENTGROUP_NUMBER(eg) ( ( traceHandle ) uxEventGroupGetNumber(eg) ) +#define TRACE_SET_EVENTGROUP_NUMBER(eg) ((EventGroup_t*)eg)->uxEventGroupNumber = prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg)); +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_10_0_0) */ + + +#define TRACE_GET_STREAMBUFFER_NUMBER(sb) ( ( traceHandle ) prvTraceGetStreamBufferNumberLow16(sb) ) +#define TRACE_SET_STREAMBUFFER_NUMBER(sb) prvTraceSetStreamBufferNumberLow16(sb, (uint16_t)prvTraceGetObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(STREAMBUFFER, sb))); + +/* Generic versions */ +#define TRACE_GET_OBJECT_NUMBER(CLASS, pxObject) TRACE_GET_##CLASS##_NUMBER(pxObject) +#define TRACE_SET_OBJECT_NUMBER(CLASS, pxObject) TRACE_SET_##CLASS##_NUMBER(pxObject) + +/****************************** +* MACROS TO GET EVENT CODES * +******************************/ +#define TRACE_GET_TASK_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(TASK, kernelClass)) +#define TRACE_GET_QUEUE_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_CLASS_TRACE_CLASS(QUEUE, kernelClass)) +#define TRACE_GET_TIMER_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- +#define TRACE_GET_EVENTGROUP_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) -- THIS IS NOT USED -- +#define TRACE_GET_STREAMBUFFER_CLASS_EVENT_CODE(SERVICE, RESULT, isMessageBuffer) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + (uint8_t)isMessageBuffer) + +#define TRACE_GET_TASK_OBJECT_EVENT_CODE(SERVICE, RESULT, pxTCB) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_CLASS_TASK) +#define TRACE_GET_QUEUE_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(EVENTGROUP_##SERVICE##_##RESULT + TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxObject)) +#define TRACE_GET_TIMER_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- +#define TRACE_GET_EVENTGROUP_OBJECT_EVENT_CODE(SERVICE, RESULT, UNUSED) -- THIS IS NOT USED -- +#define TRACE_GET_STREAMBUFFER_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) (uint8_t)(TRACE_STREAMBUFFER_##SERVICE##_##RESULT + prvGetStreamBufferType(pxObject)) + +/* Generic versions */ +#define TRACE_GET_CLASS_EVENT_CODE(SERVICE, RESULT, CLASS, kernelClass) TRACE_GET_##CLASS##_CLASS_EVENT_CODE(SERVICE, RESULT, kernelClass) +#define TRACE_GET_OBJECT_EVENT_CODE(SERVICE, RESULT, CLASS, pxObject) TRACE_GET_##CLASS##_OBJECT_EVENT_CODE(SERVICE, RESULT, pxObject) + +/****************************** +* SPECIAL MACROS FOR TASKS * +******************************/ +#define TRACE_GET_TASK_PRIORITY(pxTCB) ((uint8_t)pxTCB->uxPriority) +#define TRACE_GET_TASK_NAME(pxTCB) ((char*)pxTCB->pcTaskName) + +/*** The trace macros for snapshot mode **************************************/ + +#if defined(configUSE_TICKLESS_IDLE) +#if (configUSE_TICKLESS_IDLE != 0) + +#undef traceLOW_POWER_IDLE_BEGIN +#define traceLOW_POWER_IDLE_BEGIN() \ + { \ + extern uint32_t trace_disable_timestamp; \ + prvTraceStoreLowPower(0); \ + trace_disable_timestamp = 1; \ + } + +#undef traceLOW_POWER_IDLE_END +#define traceLOW_POWER_IDLE_END() \ + { \ + extern uint32_t trace_disable_timestamp; \ + trace_disable_timestamp = 0; \ + prvTraceStoreLowPower(1); \ + } + +#endif /* configUSE_TICKLESS_IDLE != 0 */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* A macro that will update the tick count when returning from tickless idle */ +#undef traceINCREASE_TICK_COUNT +#define traceINCREASE_TICK_COUNT( xCount ) + +/* Called for each task that becomes ready */ +#undef traceMOVED_TASK_TO_READY_STATE +#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB); + +/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ +#undef traceTASK_INCREMENT_TICK + +#if (TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4) + +#define traceTASK_INCREMENT_TICK( xTickCount ) \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); } + +#else + +#define traceTASK_INCREMENT_TICK( xTickCount ) \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { trcKERNEL_HOOKS_INCREMENT_TICK(); } \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdFALSE) { trcKERNEL_HOOKS_NEW_TIME(DIV_NEW_TIME, xTickCount + 1); } + +#endif + +/* Called on each task-switch */ +#undef traceTASK_SWITCHED_IN +#define traceTASK_SWITCHED_IN() \ + trcKERNEL_HOOKS_TASK_SWITCH(TRACE_GET_CURRENT_TASK()); + +/* Called on vTaskSuspend */ +#undef traceTASK_SUSPEND +#define traceTASK_SUSPEND( pxTaskToSuspend ) \ + trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); + +/* Called from special case with timer only */ +#undef traceTASK_DELAY_SUSPEND +#define traceTASK_DELAY_SUSPEND( pxTaskToSuspend ) \ + trcKERNEL_HOOKS_TASK_SUSPEND(TASK_SUSPEND, pxTaskToSuspend); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ +#undef traceTASK_DELAY +#define traceTASK_DELAY() \ + trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY, pxCurrentTCB, xTicksToDelay); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ +#undef traceTASK_DELAY_UNTIL +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 +#define traceTASK_DELAY_UNTIL(xTimeToWake) \ + trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_DELAY_UNTIL() \ + trcKERNEL_HOOKS_TASK_DELAY(TASK_DELAY_UNTIL, pxCurrentTCB, xTimeToWake); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +/* Called on vTaskCreate */ +#undef traceTASK_CREATE +#define traceTASK_CREATE(pxNewTCB) \ + if (pxNewTCB != NULL) \ + { \ + trcKERNEL_HOOKS_TASK_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, SUCCESS, TASK, pxNewTCB), TASK, pxNewTCB); \ + } + +/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ +#undef traceTASK_CREATE_FAILED +#define traceTASK_CREATE_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, FAILED, TASK, NOT_USED), 0); + +/* Called on vTaskDelete */ +#undef traceTASK_DELETE +#define traceTASK_DELETE( pxTaskToDelete ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_TASK_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, SUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, SUCCESS, TASK, pxTaskToDelete), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, SUCCESS, TASK, pxTaskToDelete), pxTaskToDelete); \ + TRACE_EXIT_CRITICAL_SECTION(); } + +/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ +#undef traceQUEUE_CREATE +#define traceQUEUE_CREATE( pxNewQueue ) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, SUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); + +/* Called in xQueueCreate, if the queue creation fails */ +#undef traceQUEUE_CREATE_FAILED +#define traceQUEUE_CREATE_FAILED( queueType ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, FAILED, QUEUE, queueType), 0); + +/* Called on vQueueDelete */ +#undef traceQUEUE_DELETE +#define traceQUEUE_DELETE( pxQueue ) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, SUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, SUCCESS, QUEUE, pxQueue), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + TRACE_EXIT_CRITICAL_SECTION(); } + +/* This macro is not necessary as of FreeRTOS v9.0.0 */ +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) +/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ +#undef traceCREATE_MUTEX +#define traceCREATE_MUTEX( pxNewQueue ) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, SUCCESS, QUEUE, pxNewQueue), QUEUE, pxNewQueue); + +/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ +#undef traceCREATE_MUTEX_FAILED +#define traceCREATE_MUTEX_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, FAILED, QUEUE, queueQUEUE_TYPE_MUTEX), 0); +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + +/* Called when the Mutex can not be given, since not holder */ +#undef traceGIVE_MUTEX_RECURSIVE_FAILED +#define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, FAILED, QUEUE, pxMutex), QUEUE, pxMutex); + +/* Called when a message is sent to a queue */ /* CS IS NEW ! */ +#undef traceQUEUE_SEND +#define traceQUEUE_SEND( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)0 : (uint8_t)(pxQueue->uxMessagesWaiting + 1)); + +/* Called when a message failed to be sent to a queue (timeout) */ +#undef traceQUEUE_SEND_FAILED +#define traceQUEUE_SEND_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called when the task is blocked due to a send operation on a full queue */ +#undef traceBLOCKING_ON_QUEUE_SEND +#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, BLOCK, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called when a message is received from a queue */ +#undef traceQUEUE_RECEIVE +#define traceQUEUE_RECEIVE( pxQueue ) \ + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) == TRACE_CLASS_MUTEX ? (uint8_t)TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()) : (uint8_t)(pxQueue->uxMessagesWaiting - 1)); + +/* Called when a receive operation on a queue fails (timeout) */ +#undef traceQUEUE_RECEIVE_FAILED +#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); \ + } + +/* Called when the task is blocked due to a receive operation on an empty queue */ +#undef traceBLOCKING_ON_QUEUE_RECEIVE +#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ + if (isQueueReceiveHookActuallyPeek) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, BLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, BLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + } \ + if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } + +/* Called on xQueuePeek */ +#undef traceQUEUE_PEEK +#define traceQUEUE_PEEK( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called on xQueuePeek fail/timeout (added in FreeRTOS v9.0.2) */ +#undef traceQUEUE_PEEK_FAILED +#define traceQUEUE_PEEK_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called on xQueuePeek blocking (added in FreeRTOS v9.0.2) */ +#undef traceBLOCKING_ON_QUEUE_PEEK +#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(PEEK, BLOCK, QUEUE, pxQueue), QUEUE, pxQueue); \ + if (TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, pxQueue) != TRACE_CLASS_MUTEX) \ + { \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); \ + } + +/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ +#undef traceQUEUE_SEND_FROM_ISR +#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting + 1)); + +/* Called when a message send from interrupt context fails (since the queue was full) */ +#undef traceQUEUE_SEND_FROM_ISR_FAILED +#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ +#undef traceQUEUE_RECEIVE_FROM_ISR +#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, SUCCESS, QUEUE, pxQueue), QUEUE, pxQueue); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(QUEUE, pxQueue, (uint8_t)(pxQueue->uxMessagesWaiting - 1)); + +/* Called when a message receive from interrupt context fails (since the queue was empty) */ +#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED +#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, FAILED, QUEUE, pxQueue), QUEUE, pxQueue); + +#undef traceQUEUE_REGISTRY_ADD +#define traceQUEUE_REGISTRY_ADD(object, name) prvTraceSetObjectName(TRACE_GET_OBJECT_TRACE_CLASS(QUEUE, object), TRACE_GET_OBJECT_NUMBER(QUEUE, object), name); + +/* Called in vTaskPrioritySet */ +#undef traceTASK_PRIORITY_SET +#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_SET, pxTask, uxNewPriority); + +/* Called in vTaskPriorityInherit, which is called by Mutex operations */ +#undef traceTASK_PRIORITY_INHERIT +#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_INHERIT, pxTask, uxNewPriority); + +/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ +#undef traceTASK_PRIORITY_DISINHERIT +#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ + trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(TASK_PRIORITY_DISINHERIT, pxTask, uxNewPriority); + +/* Called in vTaskResume */ +#undef traceTASK_RESUME +#define traceTASK_RESUME( pxTaskToResume ) \ + trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME, pxTaskToResume); + +/* Called in vTaskResumeFromISR */ +#undef traceTASK_RESUME_FROM_ISR +#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ + trcKERNEL_HOOKS_TASK_RESUME(TASK_RESUME_FROM_ISR, pxTaskToResume); + + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) + +extern void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t size); + +/* MALLOC and FREE are always stored, no matter if they happen inside filtered task */ +#undef traceMALLOC +#define traceMALLOC( pvAddress, uiSize ) \ + {if (pvAddress != 0) vTraceStoreMemMangEvent(MEM_MALLOC_SIZE, ( uint32_t ) pvAddress, (int32_t)uiSize); } + +#undef traceFREE +#define traceFREE( pvAddress, uiSize ) \ + {vTraceStoreMemMangEvent(MEM_FREE_SIZE, ( uint32_t ) pvAddress, -((int32_t)uiSize)); } + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0 && TRC_CFG_INCLUDE_TIMER_EVENTS == 1) + +/* Called in timer.c - xTimerCreate */ +#undef traceTIMER_CREATE +#define traceTIMER_CREATE(tmr) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TIMER_CREATE, TIMER, tmr); + +#undef traceTIMER_CREATE_FAILED +#define traceTIMER_CREATE_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TIMER_CREATE_FAILED, 0); + +/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ +#undef traceTIMER_COMMAND_SEND +#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ + if (xCommandID > tmrCOMMAND_START_DONT_TRACE) \ + { \ + if (xCommandID == tmrCOMMAND_CHANGE_PERIOD) \ + { \ + if (xReturn == pdPASS) { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD, TIMER, tmr, xOptionalValue); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TIMER_CHANGE_PERIOD_FAILED, TIMER, tmr, xOptionalValue); \ + } \ + } \ + else if ((xCommandID == tmrCOMMAND_DELETE) && (xReturn == pdPASS)) \ + { \ + trcKERNEL_HOOKS_OBJECT_DELETE(TIMER_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_SUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), EVENTGROUP_OBJCLOSE_PROP_SUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(TIMER, tmr), TIMER, tmr); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENTGROUP_TIMER + (uint32_t)xCommandID + ((xReturn == pdPASS) ? 0 : (TIMER_CREATE_FAILED - TIMER_CREATE)), TIMER, tmr, xOptionalValue); \ + }\ + } + +#undef traceTIMER_EXPIRED +#define traceTIMER_EXPIRED(tmr) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TIMER_EXPIRED, TIMER, tmr); + +#endif + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) + +#undef tracePEND_FUNC_CALL +#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ + if (ret == pdPASS){ \ + trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(PEND_FUNC_CALL_FAILED, TASK, xTimerGetTimerDaemonTaskHandle() ); \ + } + +#undef tracePEND_FUNC_CALL_FROM_ISR +#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ + if (! uiInEventGroupSetBitsFromISR){ prvTraceStoreKernelCall(PEND_FUNC_CALL_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTimerGetTimerDaemonTaskHandle()) ); } \ + uiInEventGroupSetBitsFromISR = 0; + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */ + +#endif /* (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0 && TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) + +#undef traceEVENT_GROUP_CREATE +#define traceEVENT_GROUP_CREATE(eg) \ + trcKERNEL_HOOKS_OBJECT_CREATE(EVENT_GROUP_CREATE, EVENTGROUP, eg); + +#undef traceEVENT_GROUP_CREATE_FAILED +#define traceEVENT_GROUP_CREATE_FAILED() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(EVENT_GROUP_CREATE_FAILED, 0); + +#undef traceEVENT_GROUP_DELETE +#define traceEVENT_GROUP_DELETE(eg) \ + { TRACE_ALLOC_CRITICAL_SECTION(); \ + TRACE_ENTER_CRITICAL_SECTION(); \ + trcKERNEL_HOOKS_OBJECT_DELETE(EVENT_GROUP_DELETE_OBJ, EVENTGROUP_OBJCLOSE_NAME_SUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP_OBJCLOSE_NAME_SUCCESS + TRACE_GET_OBJECT_TRACE_CLASS(EVENTGROUP, eg), EVENTGROUP, eg); \ + TRACE_EXIT_CRITICAL_SECTION(); } + +#undef traceEVENT_GROUP_SYNC_BLOCK +#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_BLOCK, EVENTGROUP, eg, bitsToWaitFor); + +#undef traceEVENT_GROUP_SYNC_END +#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ + if (wasTimeout) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END_FAILED, EVENTGROUP, eg, bitsToWaitFor); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SYNC_END, EVENTGROUP, eg, bitsToWaitFor); \ + } + +#undef traceEVENT_GROUP_WAIT_BITS_BLOCK +#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_BLOCK, EVENTGROUP, eg, bitsToWaitFor); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +#undef traceEVENT_GROUP_WAIT_BITS_END +#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ + if (wasTimeout) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END_FAILED, EVENTGROUP, eg, bitsToWaitFor); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_WAIT_BITS_END, EVENTGROUP, eg, bitsToWaitFor); \ + } + +#undef traceEVENT_GROUP_CLEAR_BITS +#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS, EVENTGROUP, eg, bitsToClear); + +#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR +#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_CLEAR_BITS_FROM_ISR, EVENTGROUP, eg, bitsToClear); + +#undef traceEVENT_GROUP_SET_BITS +#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS, EVENTGROUP, eg, bitsToSet); + +#undef traceEVENT_GROUP_SET_BITS_FROM_ISR +#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(EVENT_GROUP_SET_BITS_FROM_ISR, EVENTGROUP, eg, bitsToSet); \ + uiInEventGroupSetBitsFromISR = 1; + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0 && TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1 && TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0) +#undef traceTASK_NOTIFY_TAKE +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) +#define traceTASK_NOTIFY_TAKE() \ + if (pxCurrentTCB->eNotifyState == eNotified){ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ + } \ + else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_FAILED, TASK, pxCurrentTCB, xTicksToWait); \ + } +#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_NOTIFY_TAKE() \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE, TASK, pxCurrentTCB, xTicksToWait); \ + }else{ \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_FAILED, TASK, pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ + +#undef traceTASK_NOTIFY_TAKE_BLOCK +#define traceTASK_NOTIFY_TAKE_BLOCK() \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(TRACE_TASK_NOTIFY_TAKE_BLOCK, TASK, pxCurrentTCB, xTicksToWait); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +#undef traceTASK_NOTIFY_WAIT +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) +#define traceTASK_NOTIFY_WAIT() \ + if (pxCurrentTCB->eNotifyState == eNotified){ \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + }else{ \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_FAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait);} +#else /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_NOTIFY_WAIT() \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED){ \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + }else{ \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_FAILED, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); } +#endif /* TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0 */ + +#undef traceTASK_NOTIFY_WAIT_BLOCK +#define traceTASK_NOTIFY_WAIT_BLOCK() \ + prvTraceStoreKernelCallWithParam(TRACE_TASK_NOTIFY_WAIT_BLOCK, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxCurrentTCB), xTicksToWait); \ + trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED(); + +#undef traceTASK_NOTIFY +#define traceTASK_NOTIFY() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); + +#undef traceTASK_NOTIFY_FROM_ISR +#define traceTASK_NOTIFY_FROM_ISR() \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); + +#undef traceTASK_NOTIFY_GIVE_FROM_ISR +#define traceTASK_NOTIFY_GIVE_FROM_ISR() \ + prvTraceStoreKernelCall(TRACE_TASK_NOTIFY_GIVE_FROM_ISR, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(xTaskToNotify)); + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +#undef traceSTREAM_BUFFER_CREATE +#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + trcKERNEL_HOOKS_OBJECT_CREATE(TRACE_GET_OBJECT_EVENT_CODE(CREATE_OBJ, SUCCESS, STREAMBUFFER, pxStreamBuffer), STREAMBUFFER, pxStreamBuffer); + +#undef traceSTREAM_BUFFER_CREATE_FAILED +#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(TRACE_GET_CLASS_EVENT_CODE(CREATE_OBJ, FAILED, STREAMBUFFER, xIsMessageBuffer), 0); + +#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED +#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + +#undef traceSTREAM_BUFFER_DELETE +#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + trcKERNEL_HOOKS_OBJECT_DELETE(TRACE_GET_OBJECT_EVENT_CODE(DELETE_OBJ, SUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_NAME, SUCCESS, STREAMBUFFER, xStreamBuffer), TRACE_GET_OBJECT_EVENT_CODE(OBJCLOSE_PROP, SUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_RESET +#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(prvGetStreamBufferType(xStreamBuffer) > 0 ? TRACE_MESSAGEBUFFER_RESET : TRACE_STREAMBUFFER_RESET, STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, 0); + +#undef traceSTREAM_BUFFER_SEND +#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, SUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_SEND +#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, BLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FAILED +#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND, FAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE +#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, SUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + + +#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE +#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, BLOCK, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE_FAILED +#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE, FAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FROM_ISR +#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if( xReturn > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, SUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(SEND_FROM_ISR, FAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + } + +#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR +#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ + if( xReceivedLength > ( size_t ) 0 ) \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, SUCCESS, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + trcKERNEL_HOOKS_SET_OBJECT_STATE(STREAMBUFFER, xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + trcKERNEL_HOOKS_KERNEL_SERVICE(TRACE_GET_OBJECT_EVENT_CODE(RECEIVE_FROM_ISR, FAILED, STREAMBUFFER, xStreamBuffer), STREAMBUFFER, xStreamBuffer); \ + } + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#endif /*#if TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT */ + +/******************************************************************************/ +/*** Definitions for Streaming mode *******************************************/ +/******************************************************************************/ +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +/******************************************************************************* +* vTraceStoreKernelObjectName +* +* Set the name for a kernel object (defined by its address). +******************************************************************************/ +void vTraceStoreKernelObjectName(void* object, const char* name); + +/******************************************************************************* +* prvIsNewTCB +* +* Tells if this task is already executing, or if there has been a task-switch. +* Assumed to be called within a trace hook in kernel context. +*******************************************************************************/ +uint32_t prvIsNewTCB(void* pNewTCB); + +#define TRACE_GET_CURRENT_TASK() prvTraceGetCurrentTaskHandle() + +/*************************************************************************/ +/* KERNEL SPECIFIC OBJECT CONFIGURATION */ +/*************************************************************************/ + +/******************************************************************************* + * The event codes - should match the offline config file. + ******************************************************************************/ + +/*** Event codes for streaming - should match the Tracealyzer config file *****/ +#define PSF_EVENT_NULL_EVENT 0x00 + +#define PSF_EVENT_TRACE_START 0x01 +#define PSF_EVENT_TS_CONFIG 0x02 +#define PSF_EVENT_OBJ_NAME 0x03 +#define PSF_EVENT_TASK_PRIORITY 0x04 +#define PSF_EVENT_TASK_PRIO_INHERIT 0x05 +#define PSF_EVENT_TASK_PRIO_DISINHERIT 0x06 +#define PSF_EVENT_DEFINE_ISR 0x07 + +#define PSF_EVENT_TASK_CREATE 0x10 +#define PSF_EVENT_QUEUE_CREATE 0x11 +#define PSF_EVENT_SEMAPHORE_BINARY_CREATE 0x12 +#define PSF_EVENT_MUTEX_CREATE 0x13 +#define PSF_EVENT_TIMER_CREATE 0x14 +#define PSF_EVENT_EVENTGROUP_CREATE 0x15 +#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE 0x16 +#define PSF_EVENT_MUTEX_RECURSIVE_CREATE 0x17 +#define PSF_EVENT_STREAMBUFFER_CREATE 0x18 +#define PSF_EVENT_MESSAGEBUFFER_CREATE 0x19 + +#define PSF_EVENT_TASK_DELETE 0x20 +#define PSF_EVENT_QUEUE_DELETE 0x21 +#define PSF_EVENT_SEMAPHORE_DELETE 0x22 +#define PSF_EVENT_MUTEX_DELETE 0x23 +#define PSF_EVENT_TIMER_DELETE 0x24 +#define PSF_EVENT_EVENTGROUP_DELETE 0x25 +#define PSF_EVENT_STREAMBUFFER_DELETE 0x28 +#define PSF_EVENT_MESSAGEBUFFER_DELETE 0x29 + +#define PSF_EVENT_TASK_READY 0x30 +#define PSF_EVENT_NEW_TIME 0x31 +#define PSF_EVENT_NEW_TIME_SCHEDULER_SUSPENDED 0x32 +#define PSF_EVENT_ISR_BEGIN 0x33 +#define PSF_EVENT_ISR_RESUME 0x34 +#define PSF_EVENT_TS_BEGIN 0x35 +#define PSF_EVENT_TS_RESUME 0x36 +#define PSF_EVENT_TASK_ACTIVATE 0x37 + +#define PSF_EVENT_MALLOC 0x38 +#define PSF_EVENT_FREE 0x39 + +#define PSF_EVENT_LOWPOWER_BEGIN 0x3A +#define PSF_EVENT_LOWPOWER_END 0x3B + +#define PSF_EVENT_IFE_NEXT 0x3C +#define PSF_EVENT_IFE_DIRECT 0x3D + +#define PSF_EVENT_TASK_CREATE_FAILED 0x40 +#define PSF_EVENT_QUEUE_CREATE_FAILED 0x41 +#define PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED 0x42 +#define PSF_EVENT_MUTEX_CREATE_FAILED 0x43 +#define PSF_EVENT_TIMER_CREATE_FAILED 0x44 +#define PSF_EVENT_EVENTGROUP_CREATE_FAILED 0x45 +#define PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED 0x46 +#define PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED 0x47 +#define PSF_EVENT_STREAMBUFFER_CREATE_FAILED 0x49 +#define PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED 0x4A + +#define PSF_EVENT_TIMER_DELETE_FAILED 0x48 + +#define PSF_EVENT_QUEUE_SEND 0x50 +#define PSF_EVENT_SEMAPHORE_GIVE 0x51 +#define PSF_EVENT_MUTEX_GIVE 0x52 + +#define PSF_EVENT_QUEUE_SEND_FAILED 0x53 +#define PSF_EVENT_SEMAPHORE_GIVE_FAILED 0x54 +#define PSF_EVENT_MUTEX_GIVE_FAILED 0x55 + +#define PSF_EVENT_QUEUE_SEND_BLOCK 0x56 +#define PSF_EVENT_SEMAPHORE_GIVE_BLOCK 0x57 +#define PSF_EVENT_MUTEX_GIVE_BLOCK 0x58 + +#define PSF_EVENT_QUEUE_SEND_FROMISR 0x59 +#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR 0x5A + +#define PSF_EVENT_QUEUE_SEND_FROMISR_FAILED 0x5C +#define PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED 0x5D + +#define PSF_EVENT_QUEUE_RECEIVE 0x60 +#define PSF_EVENT_SEMAPHORE_TAKE 0x61 +#define PSF_EVENT_MUTEX_TAKE 0x62 + +#define PSF_EVENT_QUEUE_RECEIVE_FAILED 0x63 +#define PSF_EVENT_SEMAPHORE_TAKE_FAILED 0x64 +#define PSF_EVENT_MUTEX_TAKE_FAILED 0x65 + +#define PSF_EVENT_QUEUE_RECEIVE_BLOCK 0x66 +#define PSF_EVENT_SEMAPHORE_TAKE_BLOCK 0x67 +#define PSF_EVENT_MUTEX_TAKE_BLOCK 0x68 + +#define PSF_EVENT_QUEUE_RECEIVE_FROMISR 0x69 +#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR 0x6A + +#define PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED 0x6C +#define PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED 0x6D + +#define PSF_EVENT_QUEUE_PEEK 0x70 +#define PSF_EVENT_SEMAPHORE_PEEK 0x71 +#define PSF_EVENT_MUTEX_PEEK 0x72 + +#define PSF_EVENT_QUEUE_PEEK_FAILED 0x73 +#define PSF_EVENT_SEMAPHORE_PEEK_FAILED 0x74 +#define PSF_EVENT_MUTEX_PEEK_FAILED 0x75 + +#define PSF_EVENT_QUEUE_PEEK_BLOCK 0x76 +#define PSF_EVENT_SEMAPHORE_PEEK_BLOCK 0x77 +#define PSF_EVENT_MUTEX_PEEK_BLOCK 0x78 + +#define PSF_EVENT_TASK_DELAY_UNTIL 0x79 +#define PSF_EVENT_TASK_DELAY 0x7A +#define PSF_EVENT_TASK_SUSPEND 0x7B +#define PSF_EVENT_TASK_RESUME 0x7C +#define PSF_EVENT_TASK_RESUME_FROMISR 0x7D + +#define PSF_EVENT_TIMER_PENDFUNCCALL 0x80 +#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR 0x81 +#define PSF_EVENT_TIMER_PENDFUNCCALL_FAILED 0x82 +#define PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED 0x83 + +#define PSF_EVENT_USER_EVENT 0x90 + +#define PSF_EVENT_TIMER_START 0xA0 +#define PSF_EVENT_TIMER_RESET 0xA1 +#define PSF_EVENT_TIMER_STOP 0xA2 +#define PSF_EVENT_TIMER_CHANGEPERIOD 0xA3 +#define PSF_EVENT_TIMER_START_FROMISR 0xA4 +#define PSF_EVENT_TIMER_RESET_FROMISR 0xA5 +#define PSF_EVENT_TIMER_STOP_FROMISR 0xA6 +#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR 0xA7 +#define PSF_EVENT_TIMER_START_FAILED 0xA8 +#define PSF_EVENT_TIMER_RESET_FAILED 0xA9 +#define PSF_EVENT_TIMER_STOP_FAILED 0xAA +#define PSF_EVENT_TIMER_CHANGEPERIOD_FAILED 0xAB +#define PSF_EVENT_TIMER_START_FROMISR_FAILED 0xAC +#define PSF_EVENT_TIMER_RESET_FROMISR_FAILED 0xAD +#define PSF_EVENT_TIMER_STOP_FROMISR_FAILED 0xAE +#define PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED 0xAF + +#define PSF_EVENT_EVENTGROUP_SYNC 0xB0 +#define PSF_EVENT_EVENTGROUP_WAITBITS 0xB1 +#define PSF_EVENT_EVENTGROUP_CLEARBITS 0xB2 +#define PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR 0xB3 +#define PSF_EVENT_EVENTGROUP_SETBITS 0xB4 +#define PSF_EVENT_EVENTGROUP_SETBITS_FROMISR 0xB5 +#define PSF_EVENT_EVENTGROUP_SYNC_BLOCK 0xB6 +#define PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK 0xB7 +#define PSF_EVENT_EVENTGROUP_SYNC_FAILED 0xB8 +#define PSF_EVENT_EVENTGROUP_WAITBITS_FAILED 0xB9 + +#define PSF_EVENT_QUEUE_SEND_FRONT 0xC0 +#define PSF_EVENT_QUEUE_SEND_FRONT_FAILED 0xC1 +#define PSF_EVENT_QUEUE_SEND_FRONT_BLOCK 0xC2 +#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR 0xC3 +#define PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED 0xC4 +#define PSF_EVENT_MUTEX_GIVE_RECURSIVE 0xC5 +#define PSF_EVENT_MUTEX_GIVE_RECURSIVE_FAILED 0xC6 +#define PSF_EVENT_MUTEX_TAKE_RECURSIVE 0xC7 +#define PSF_EVENT_MUTEX_TAKE_RECURSIVE_FAILED 0xC8 + +#define PSF_EVENT_TASK_NOTIFY 0xC9 +#define PSF_EVENT_TASK_NOTIFY_TAKE 0xCA +#define PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK 0xCB +#define PSF_EVENT_TASK_NOTIFY_TAKE_FAILED 0xCC +#define PSF_EVENT_TASK_NOTIFY_WAIT 0xCD +#define PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK 0xCE +#define PSF_EVENT_TASK_NOTIFY_WAIT_FAILED 0xCF +#define PSF_EVENT_TASK_NOTIFY_FROM_ISR 0xD0 +#define PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR 0xD1 + +#define PSF_EVENT_TIMER_EXPIRED 0xD2 + +#define PSF_EVENT_STREAMBUFFER_SEND 0xD3 +#define PSF_EVENT_STREAMBUFFER_SEND_BLOCK 0xD4 +#define PSF_EVENT_STREAMBUFFER_SEND_FAILED 0xD5 +#define PSF_EVENT_STREAMBUFFER_RECEIVE 0xD6 +#define PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK 0xD7 +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED 0xD8 +#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR 0xD9 +#define PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED 0xDA +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR 0xDB +#define PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED 0xDC +#define PSF_EVENT_STREAMBUFFER_RESET 0xDD + +#define PSF_EVENT_MESSAGEBUFFER_SEND 0xDE +#define PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK 0xDF +#define PSF_EVENT_MESSAGEBUFFER_SEND_FAILED 0xE0 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE 0xE1 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK 0xE2 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED 0xE3 +#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR 0xE4 +#define PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED 0xE5 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR 0xE6 +#define PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED 0xE7 +#define PSF_EVENT_MESSAGEBUFFER_RESET 0xE8 + +/*** The trace macros for streaming ******************************************/ + +#if (defined(configUSE_TICKLESS_IDLE) && configUSE_TICKLESS_IDLE != 0) + +#undef traceLOW_POWER_IDLE_BEGIN +#define traceLOW_POWER_IDLE_BEGIN() \ + { \ + prvTraceStoreEvent1(PSF_EVENT_LOWPOWER_BEGIN, xExpectedIdleTime); \ + } + +#undef traceLOW_POWER_IDLE_END +#define traceLOW_POWER_IDLE_END() \ + { \ + prvTraceStoreEvent0(PSF_EVENT_LOWPOWER_END); \ + } + +#endif + +/* A macro that will update the tick count when returning from tickless idle */ +#undef traceINCREASE_TICK_COUNT +/* Note: This can handle time adjustments of max 2^32 ticks, i.e., 35 seconds at 120 MHz. Thus, tick-less idle periods longer than 2^32 ticks will appear "compressed" on the time line.*/ +#define traceINCREASE_TICK_COUNT( xCount ) { extern uint32_t uiTraceTickCount; uiTraceTickCount += xCount; } + +/* Called for each task that becomes ready */ +#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) +#undef traceMOVED_TASK_TO_READY_STATE +#define traceMOVED_TASK_TO_READY_STATE( pxTCB ) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_READY, (uint32_t)pxTCB); +#endif + +#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1) +#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) if (uxSchedulerSuspended == (unsigned portBASE_TYPE) pdFALSE) { prvTraceStoreEvent1(PSF_EVENT_NEW_TIME, (uint32_t)(xTickCount + 1)); } +#else +#define OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#endif + +/* Called on each OS tick. Will call uiPortGetTimestamp to make sure it is called at least once every OS tick. */ +#undef traceTASK_INCREMENT_TICK +#if TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 +#define traceTASK_INCREMENT_TICK( xTickCount ) \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxMissedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \ + OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#else +#define traceTASK_INCREMENT_TICK( xTickCount ) \ + if (uxSchedulerSuspended == ( unsigned portBASE_TYPE ) pdTRUE || uxPendedTicks == 0) { extern uint32_t uiTraceTickCount; uiTraceTickCount++; } \ + OS_TICK_EVENT(uxSchedulerSuspended, xTickCount) +#endif /* TRC_CFG_FREERTOS_VERSION <= TRC_FREERTOS_VERSION_7_4 */ + +#undef traceTASK_CREATE +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 +#define traceTASK_CREATE(pxNewTCB) \ + if (pxNewTCB != NULL) \ + { \ + prvTraceSaveSymbol(pxNewTCB, pxNewTCB->pcTaskName); \ + prvTraceSaveObjectData(pxNewTCB, pxNewTCB->uxPriority); \ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, pxNewTCB->pcTaskName, pxNewTCB); \ + TRACE_SET_TASK_FILTER(pxNewTCB, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, pxNewTCB->uxPriority); \ + } +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_CREATE(pxNewTCB) \ + if (pxNewTCB != NULL) \ + { \ + prvTraceSaveSymbol(pxNewTCB, (const char*)pcName); \ + prvTraceSaveObjectData(pxNewTCB, uxPriority); \ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)pcName, pxNewTCB); \ + TRACE_SET_TASK_FILTER(pxNewTCB, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_TASK_CREATE, (uint32_t)pxNewTCB, uxPriority); \ + } +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +/* Called in vTaskCreate, if it fails (typically if the stack can not be allocated) */ +#undef traceTASK_CREATE_FAILED +#define traceTASK_CREATE_FAILED() \ + prvTraceStoreEvent0(PSF_EVENT_TASK_CREATE_FAILED); + +/* Called on vTaskDelete */ +#undef traceTASK_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. +#define traceTASK_DELETE( pxTaskToDelete ) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_DELETE, (uint32_t)pxTaskToDelete, (pxTaskToDelete != NULL) ? (pxTaskToDelete->uxPriority) : 0); \ + prvTraceDeleteSymbol(pxTaskToDelete); \ + prvTraceDeleteObjectData(pxTaskToDelete); + +/* Called on each task-switch */ +#undef traceTASK_SWITCHED_IN +#define traceTASK_SWITCHED_IN() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (prvIsNewTCB(pxCurrentTCB)) \ + { \ + prvTraceStoreEvent2(PSF_EVENT_TASK_ACTIVATE, (uint32_t)pxCurrentTCB, pxCurrentTCB->uxPriority); \ + } + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +/* Called on vTaskSuspend */ +#undef traceTASK_SUSPEND +#define traceTASK_SUSPEND( pxTaskToSuspend ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_SUSPEND, (uint32_t)pxTaskToSuspend); + +/* Called on vTaskDelay - note the use of FreeRTOS variable xTicksToDelay */ +#undef traceTASK_DELAY +#define traceTASK_DELAY() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY, xTicksToDelay); + +/* Called on vTaskDelayUntil - note the use of FreeRTOS variable xTimeToWake */ +#undef traceTASK_DELAY_UNTIL +#if TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 +#define traceTASK_DELAY_UNTIL(xTimeToWake) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_DELAY_UNTIL() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_DELAY_UNTIL, (uint32_t)xTimeToWake); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceQUEUE_CREATE_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \ + break; +#else +#define traceQUEUE_CREATE_HELPER() +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + +/* Called in xQueueCreate, and thereby for all other object based on queues, such as semaphores. */ +#undef traceQUEUE_CREATE +#define traceQUEUE_CREATE( pxNewQueue )\ + TRACE_SET_OBJECT_FILTER(QUEUE, pxNewQueue, CurrentFilterGroup); \ + switch (pxNewQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE, (uint32_t)pxNewQueue, uxQueueLength); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE, (uint32_t)pxNewQueue); \ + break; \ + traceQUEUE_CREATE_HELPER() \ + } + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceQUEUE_CREATE_FAILED_HELPER() \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE_FAILED, 0); \ + break; +#else +#define traceQUEUE_CREATE_FAILED_HELPER() +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + +/* Called in xQueueCreate, if the queue creation fails */ +#undef traceQUEUE_CREATE_FAILED +#define traceQUEUE_CREATE_FAILED( queueType ) \ + switch (queueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_CREATE_FAILED, 0, uxQueueLength); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent1(PSF_EVENT_SEMAPHORE_BINARY_CREATE_FAILED, 0); \ + break; \ + traceQUEUE_CREATE_FAILED_HELPER() \ + } + +#undef traceQUEUE_DELETE // We don't allow for filtering out "delete" events. They are important and not very frequent. Moreover, we can't exclude create events, so this should be symmetrical. +#define traceQUEUE_DELETE( pxQueue ) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_DELETE, (uint32_t)pxQueue, (pxQueue != NULL) ? (pxQueue->uxMessagesWaiting) : 0); \ + break; \ + } \ + prvTraceDeleteSymbol(pxQueue); + +/* Called in xQueueCreateCountingSemaphore, if the queue creation fails */ +#undef traceCREATE_COUNTING_SEMAPHORE +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxMaxCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6) +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxInitialCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)xHandle, uxCountValue); +#else +#define traceCREATE_COUNTING_SEMAPHORE() \ + TRACE_SET_OBJECT_FILTER(QUEUE, pxHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE, (uint32_t)pxHandle, uxCountValue); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ + +#undef traceCREATE_COUNTING_SEMAPHORE_FAILED +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxMaxCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_5_OR_7_6) +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxInitialCount); +#elif (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_7_4) +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + TRACE_SET_OBJECT_FILTER(QUEUE, xHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue); +#else +#define traceCREATE_COUNTING_SEMAPHORE_FAILED() \ + TRACE_SET_OBJECT_FILTER(QUEUE, pxHandle, CurrentFilterGroup); \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_COUNTING_CREATE_FAILED, 0, uxCountValue); +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ + + +/* This macro is not necessary as of FreeRTOS v9.0.0 */ +#if (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) +/* Called in xQueueCreateMutex, and thereby also from xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex */ +#undef traceCREATE_MUTEX +#define traceCREATE_MUTEX( pxNewQueue ) \ + TRACE_SET_OBJECT_FILTER(TIMER, pxNewQueue, CurrentFilterGroup); \ + switch (pxNewQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE, (uint32_t)pxNewQueue); \ + break; \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_RECURSIVE_CREATE, (uint32_t)pxNewQueue); \ + break; \ + } + +/* Called in xQueueCreateMutex when the operation fails (when memory allocation fails) */ +#undef traceCREATE_MUTEX_FAILED +#define traceCREATE_MUTEX_FAILED() \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_CREATE_FAILED, 0); +#endif /* (TRC_CFG_FREERTOS_VERSION < TRC_FREERTOS_VERSION_9_0_0) */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a message is sent to a queue */ /* CS IS NEW ! */ +#undef traceQUEUE_SEND +#define traceQUEUE_SEND( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND : PSF_EVENT_QUEUE_SEND_FRONT, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE, (uint32_t)pxQueue); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a message failed to be sent to a queue (timeout) */ +#undef traceQUEUE_SEND_FAILED +#define traceQUEUE_SEND_FAILED( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_FAILED, (uint32_t)pxQueue); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when the task is blocked due to a send operation on a full queue */ +#undef traceBLOCKING_ON_QUEUE_SEND +#define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_BLOCK : PSF_EVENT_QUEUE_SEND_FRONT_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_BLOCK, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_GIVE_BLOCK, (uint32_t)pxQueue); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +/**************************************************************************/ +/* Makes sure xQueueGiveFromISR also has a xCopyPosition parameter */ +/**************************************************************************/ +/* Helpers needed to correctly expand names */ +#define TZ__CAT2(a,b) a ## b +#define TZ__CAT(a,b) TZ__CAT2(a, b) + +/* Expands name if this header is included... uxQueueType must be a macro that only exists in queue.c or whatever, and it must expand to nothing or to something that's valid in identifiers */ +#define xQueueGiveFromISR(a,b) TZ__CAT(xQueueGiveFromISR__, uxQueueType) (a,b) + +/* If in queue.c, the "uxQueueType" macro expands to "pcHead". queueSEND_TO_BACK is the value we need to send in */ +#define xQueueGiveFromISR__pcHead(__a, __b) MyWrapper(__a, __b, const BaseType_t xCopyPosition); \ +BaseType_t xQueueGiveFromISR(__a, __b) { return MyWrapper(xQueue, pxHigherPriorityTaskWoken, queueSEND_TO_BACK); } \ +BaseType_t MyWrapper(__a, __b, const BaseType_t xCopyPosition) + +/* If not in queue.c, "uxQueueType" isn't expanded */ +#define xQueueGiveFromISR__uxQueueType(__a, __b) xQueueGiveFromISR(__a,__b) + +/**************************************************************************/ +/* End of xQueueGiveFromISR fix */ +/**************************************************************************/ + +/* Called when a message is sent from interrupt context, e.g., using xQueueSendFromISR */ +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +#undef traceQUEUE_SEND_FROM_ISR +#define traceQUEUE_SEND_FROM_ISR( pxQueue ) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting + 1); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a message send from interrupt context fails (since the queue was full) */ +#undef traceQUEUE_SEND_FROM_ISR_FAILED +#define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(xCopyPosition == queueSEND_TO_BACK ? PSF_EVENT_QUEUE_SEND_FROMISR_FAILED : PSF_EVENT_QUEUE_SEND_FRONT_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_GIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a message is received from a queue */ +#undef traceQUEUE_RECEIVE +#define traceQUEUE_RECEIVE( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + else\ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_RECEIVE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + else \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_TAKE, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + if (isQueueReceiveHookActuallyPeek) \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_TAKE, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a receive operation on a queue fails (timeout) */ +#undef traceQUEUE_RECEIVE_FAILED +#define traceQUEUE_RECEIVE_FAILED( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_FAILED : PSF_EVENT_QUEUE_RECEIVE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_FAILED : PSF_EVENT_SEMAPHORE_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_FAILED : PSF_EVENT_MUTEX_TAKE_FAILED, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when the task is blocked due to a receive operation on an empty queue */ +#undef traceBLOCKING_ON_QUEUE_RECEIVE +#define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_QUEUE_PEEK_BLOCK : PSF_EVENT_QUEUE_RECEIVE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(isQueueReceiveHookActuallyPeek ? PSF_EVENT_SEMAPHORE_PEEK_BLOCK : PSF_EVENT_SEMAPHORE_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(isQueueReceiveHookActuallyPeek ? PSF_EVENT_MUTEX_PEEK_BLOCK : PSF_EVENT_MUTEX_TAKE_BLOCK, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a peek operation on a queue fails (timeout) */ +#undef traceQUEUE_PEEK_FAILED +#define traceQUEUE_PEEK_FAILED( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_FAILED, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when the task is blocked due to a peek operation on an empty queue */ +#undef traceBLOCKING_ON_QUEUE_PEEK +#define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent2(PSF_EVENT_MUTEX_PEEK_BLOCK, (uint32_t)pxQueue, xTicksToWait); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#endif /* (TRC_CFG_FREERTOS_VERSION > TRC_FREERTOS_VERSION_9_0_1) */ + +/* Called when a message is received in interrupt context, e.g., using xQueueReceiveFromISR */ +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +#undef traceQUEUE_RECEIVE_FROM_ISR +#define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting - 1); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called when a message receive from interrupt context fails (since the queue was empty) */ +#undef traceQUEUE_RECEIVE_FROM_ISR_FAILED +#define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent2(PSF_EVENT_QUEUE_RECEIVE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent2(PSF_EVENT_SEMAPHORE_TAKE_FROMISR_FAILED, (uint32_t)pxQueue, pxQueue->uxMessagesWaiting); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +#if TRC_CFG_INCLUDE_QUEUE_EVENTS /* << EST */ +/* Called on xQueuePeek */ +#undef traceQUEUE_PEEK +#define traceQUEUE_PEEK( pxQueue ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(QUEUE, pxQueue) & CurrentFilterMask) \ + switch (pxQueue->ucQueueType) \ + { \ + case queueQUEUE_TYPE_BASE: \ + prvTraceStoreEvent3(PSF_EVENT_QUEUE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_BINARY_SEMAPHORE: \ + case queueQUEUE_TYPE_COUNTING_SEMAPHORE: \ + prvTraceStoreEvent3(PSF_EVENT_SEMAPHORE_PEEK, (uint32_t)pxQueue, xTicksToWait, pxQueue->uxMessagesWaiting); \ + break; \ + case queueQUEUE_TYPE_MUTEX: \ + case queueQUEUE_TYPE_RECURSIVE_MUTEX: \ + prvTraceStoreEvent1(PSF_EVENT_MUTEX_PEEK, (uint32_t)pxQueue); \ + break; \ + } +#endif /* TRC_CFG_INCLUDE_QUEUE_EVENTS */ /* << EST */ + +/* Called in vTaskPrioritySet */ +#undef traceTASK_PRIORITY_SET +#define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) \ + prvTraceSaveObjectData(pxTask, uxNewPriority); \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIORITY, (uint32_t)pxTask, uxNewPriority); + +/* Called in vTaskPriorityInherit, which is called by Mutex operations */ +#undef traceTASK_PRIORITY_INHERIT +#define traceTASK_PRIORITY_INHERIT( pxTask, uxNewPriority ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_INHERIT, (uint32_t)pxTask, uxNewPriority); + +/* Called in vTaskPriorityDisinherit, which is called by Mutex operations */ +#undef traceTASK_PRIORITY_DISINHERIT +#define traceTASK_PRIORITY_DISINHERIT( pxTask, uxNewPriority ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTask) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_PRIO_DISINHERIT, (uint32_t)pxTask, uxNewPriority); + +/* Called in vTaskResume */ +#undef traceTASK_RESUME +#define traceTASK_RESUME( pxTaskToResume ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTaskToResume) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME, (uint32_t)pxTaskToResume); + +/* Called in vTaskResumeFromISR */ +#undef traceTASK_RESUME_FROM_ISR +#define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) \ + if (TRACE_GET_TASK_FILTER(pxTaskToResume) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_RESUME_FROMISR, (uint32_t)pxTaskToResume); + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) + +#undef traceMALLOC +#define traceMALLOC( pvAddress, uiSize ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_MALLOC, (uint32_t)pvAddress, uiSize); + +#undef traceFREE +#define traceFREE( pvAddress, uiSize ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_FREE, (uint32_t)pvAddress, (uint32_t)(0 - uiSize)); /* "0 -" instead of just "-" to get rid of a warning... */ + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) +/* Called in timer.c - xTimerCreate */ +#undef traceTIMER_CREATE +#define traceTIMER_CREATE(tmr) \ + TRACE_SET_OBJECT_FILTER(TIMER, tmr, CurrentFilterGroup); \ + prvTraceSaveSymbol(tmr, tmr->pcTimerName); \ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, tmr->pcTimerName, tmr); \ + prvTraceStoreEvent2(PSF_EVENT_TIMER_CREATE, (uint32_t)tmr, tmr->xTimerPeriodInTicks); + +#undef traceTIMER_CREATE_FAILED +#define traceTIMER_CREATE_FAILED() \ + prvTraceStoreEvent0(PSF_EVENT_TIMER_CREATE_FAILED); + +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X) +#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ + case tmrCOMMAND_RESET: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET : PSF_EVENT_TIMER_RESET_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_START_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_START_FROMISR : PSF_EVENT_TIMER_START_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_RESET_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_RESET_FROMISR : PSF_EVENT_TIMER_RESET_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_STOP_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP_FROMISR : PSF_EVENT_TIMER_STOP_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR : PSF_EVENT_TIMER_CHANGEPERIOD_FROMISR_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ +#define traceTIMER_COMMAND_SEND_8_0_CASES(tmr) +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_8_X */ + +/* Note that xCommandID can never be tmrCOMMAND_EXECUTE_CALLBACK (-1) since the trace macro is not called in that case */ +#undef traceTIMER_COMMAND_SEND +#define traceTIMER_COMMAND_SEND(tmr, xCommandID, xOptionalValue, xReturn) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(TIMER, tmr) & CurrentFilterMask) \ + switch(xCommandID) \ + { \ + case tmrCOMMAND_START: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_START : PSF_EVENT_TIMER_START_FAILED, (uint32_t)tmr); \ + break; \ + case tmrCOMMAND_STOP: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_STOP : PSF_EVENT_TIMER_STOP_FAILED, (uint32_t)tmr); \ + break; \ + case tmrCOMMAND_CHANGE_PERIOD: \ + prvTraceStoreEvent2((xReturn == pdPASS) ? PSF_EVENT_TIMER_CHANGEPERIOD : PSF_EVENT_TIMER_CHANGEPERIOD_FAILED, (uint32_t)tmr, xOptionalValue); \ + break; \ + case tmrCOMMAND_DELETE: \ + prvTraceStoreEvent1((xReturn == pdPASS) ? PSF_EVENT_TIMER_DELETE : PSF_EVENT_TIMER_DELETE_FAILED, (uint32_t)tmr); \ + break; \ + traceTIMER_COMMAND_SEND_8_0_CASES(tmr) \ + } + +#undef traceTIMER_EXPIRED +#define traceTIMER_EXPIRED(tmr) \ + prvTraceStoreEvent2(PSF_EVENT_TIMER_EXPIRED, (uint32_t)tmr->pxCallbackFunction, (uint32_t)tmr->pvTimerID); + +#endif /* #if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_TIMER_EVENTS == 1) */ + + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) + +#undef tracePEND_FUNC_CALL +#define tracePEND_FUNC_CALL(func, arg1, arg2, ret) \ + prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL : PSF_EVENT_TIMER_PENDFUNCCALL_FAILED, (uint32_t)func); + +#undef tracePEND_FUNC_CALL_FROM_ISR +#define tracePEND_FUNC_CALL_FROM_ISR(func, arg1, arg2, ret) \ + prvTraceStoreEvent1((ret == pdPASS) ? PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR : PSF_EVENT_TIMER_PENDFUNCCALL_FROMISR_FAILED, (uint32_t)func); + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_PEND_FUNC_CALL_EVENTS == 1) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) + +#undef traceEVENT_GROUP_CREATE +#define traceEVENT_GROUP_CREATE(eg) \ + TRACE_SET_OBJECT_FILTER(EVENTGROUP, eg, CurrentFilterGroup); \ + prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_CREATE, (uint32_t)eg); + +#undef traceEVENT_GROUP_DELETE +#define traceEVENT_GROUP_DELETE(eg) \ + prvTraceStoreEvent1(PSF_EVENT_EVENTGROUP_DELETE, (uint32_t)eg); \ + prvTraceDeleteSymbol(eg); + +#undef traceEVENT_GROUP_CREATE_FAILED +#define traceEVENT_GROUP_CREATE_FAILED() \ + prvTraceStoreEvent0(PSF_EVENT_EVENTGROUP_CREATE_FAILED); + +#undef traceEVENT_GROUP_SYNC_BLOCK +#define traceEVENT_GROUP_SYNC_BLOCK(eg, bitsToSet, bitsToWaitFor) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SYNC_BLOCK, (uint32_t)eg, bitsToWaitFor); + +#undef traceEVENT_GROUP_SYNC_END +#define traceEVENT_GROUP_SYNC_END(eg, bitsToSet, bitsToWaitFor, wasTimeout) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_SYNC : PSF_EVENT_EVENTGROUP_SYNC_FAILED, (uint32_t)eg, bitsToWaitFor); + +#undef traceEVENT_GROUP_WAIT_BITS_BLOCK +#define traceEVENT_GROUP_WAIT_BITS_BLOCK(eg, bitsToWaitFor) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_WAITBITS_BLOCK, (uint32_t)eg, bitsToWaitFor); + +#undef traceEVENT_GROUP_WAIT_BITS_END +#define traceEVENT_GROUP_WAIT_BITS_END(eg, bitsToWaitFor, wasTimeout) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2((wasTimeout != pdTRUE) ? PSF_EVENT_EVENTGROUP_WAITBITS : PSF_EVENT_EVENTGROUP_WAITBITS_FAILED, (uint32_t)eg, bitsToWaitFor); + +#undef traceEVENT_GROUP_CLEAR_BITS +#define traceEVENT_GROUP_CLEAR_BITS(eg, bitsToClear) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS, (uint32_t)eg, bitsToClear); + +#undef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR +#define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR(eg, bitsToClear) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_CLEARBITS_FROMISR, (uint32_t)eg, bitsToClear); + +#undef traceEVENT_GROUP_SET_BITS +#define traceEVENT_GROUP_SET_BITS(eg, bitsToSet) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS, (uint32_t)eg, bitsToSet); + +#undef traceEVENT_GROUP_SET_BITS_FROM_ISR +#define traceEVENT_GROUP_SET_BITS_FROM_ISR(eg, bitsToSet) \ + if (TRACE_GET_OBJECT_FILTER(EVENTGROUP, eg) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_EVENTGROUP_SETBITS_FROMISR, (uint32_t)eg, bitsToSet); + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_EVENT_GROUP_EVENTS == 1) */ + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +#undef traceTASK_NOTIFY_TAKE +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceTASK_NOTIFY_TAKE() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_NOTIFY_TAKE() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->eNotifyState == eNotified) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +#undef traceTASK_NOTIFY_TAKE_BLOCK +#define traceTASK_NOTIFY_TAKE_BLOCK() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_TAKE_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); + +#undef traceTASK_NOTIFY_WAIT +#if (TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0) +#define traceTASK_NOTIFY_WAIT() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->ucNotifyState == taskNOTIFICATION_RECEIVED) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#else /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ +#define traceTASK_NOTIFY_WAIT() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask){ \ + if (pxCurrentTCB->eNotifyState == eNotified) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT, (uint32_t)pxCurrentTCB, xTicksToWait); \ + else \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_FAILED, (uint32_t)pxCurrentTCB, xTicksToWait);} +#endif /* TRC_CFG_FREERTOS_VERSION >= TRC_FREERTOS_VERSION_9_0_0 */ + +#undef traceTASK_NOTIFY_WAIT_BLOCK +#define traceTASK_NOTIFY_WAIT_BLOCK() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent2(PSF_EVENT_TASK_NOTIFY_WAIT_BLOCK, (uint32_t)pxCurrentTCB, xTicksToWait); + +#undef traceTASK_NOTIFY +#define traceTASK_NOTIFY() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY, (uint32_t)xTaskToNotify); + +#undef traceTASK_NOTIFY_FROM_ISR +#define traceTASK_NOTIFY_FROM_ISR() \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_FROM_ISR, (uint32_t)xTaskToNotify); + +#undef traceTASK_NOTIFY_GIVE_FROM_ISR +#define traceTASK_NOTIFY_GIVE_FROM_ISR() \ + prvTraceStoreEvent1(PSF_EVENT_TASK_NOTIFY_GIVE_FROM_ISR, (uint32_t)xTaskToNotify); + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#undef traceQUEUE_REGISTRY_ADD +#define traceQUEUE_REGISTRY_ADD(object, name) \ + prvTraceSaveSymbol(object, (const char*)name); \ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, object); + +#if (TRC_CFG_SCHEDULING_ONLY == 0) +#undef traceSTREAM_BUFFER_CREATE +#define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) \ + TRACE_SET_OBJECT_FILTER(STREAMBUFFER, pxStreamBuffer, CurrentFilterGroup); \ + prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE : PSF_EVENT_STREAMBUFFER_CREATE, (uint32_t)pxStreamBuffer, xBufferSizeBytes); + +#undef traceSTREAM_BUFFER_CREATE_FAILED +#define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) \ + prvTraceStoreEvent2(xIsMessageBuffer == 1 ? PSF_EVENT_MESSAGEBUFFER_CREATE_FAILED : PSF_EVENT_STREAMBUFFER_CREATE_FAILED, 0 , xBufferSizeBytes); + +#undef traceSTREAM_BUFFER_CREATE_STATIC_FAILED +#define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) \ + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) + +#undef traceSTREAM_BUFFER_DELETE +#define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_DELETE : PSF_EVENT_STREAMBUFFER_DELETE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + prvTraceDeleteSymbol(xStreamBuffer); + +#undef traceSTREAM_BUFFER_RESET +#define traceSTREAM_BUFFER_RESET( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RESET : PSF_EVENT_STREAMBUFFER_RESET, (uint32_t)xStreamBuffer, 0); + +#undef traceSTREAM_BUFFER_SEND +#define traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND : PSF_EVENT_STREAMBUFFER_SEND, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_SEND +#define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_BLOCK : PSF_EVENT_STREAMBUFFER_SEND_BLOCK, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FAILED +#define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FAILED, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE +#define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE: PSF_EVENT_STREAMBUFFER_RECEIVE, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); + +#undef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE +#define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_BLOCK: PSF_EVENT_STREAMBUFFER_RECEIVE_BLOCK, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_RECEIVE_FAILED +#define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FAILED: PSF_EVENT_STREAMBUFFER_RECEIVE_FAILED, (uint32_t)xStreamBuffer); + +#undef traceSTREAM_BUFFER_SEND_FROM_ISR +#define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + { \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + { \ + if ( xReturn > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_SEND_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_SEND_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \ + } \ + } \ + } + +#undef traceSTREAM_BUFFER_RECEIVE_FROM_ISR +#define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + { \ + if (TRACE_GET_OBJECT_FILTER(STREAMBUFFER, xStreamBuffer) & CurrentFilterMask) \ + { \ + if ( xReceivedLength > ( size_t ) 0 ) \ + { \ + prvTraceStoreEvent2(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR, (uint32_t)xStreamBuffer, prvBytesInBuffer(xStreamBuffer)); \ + } \ + else \ + { \ + prvTraceStoreEvent1(prvGetStreamBufferType(xStreamBuffer) > 0 ? PSF_EVENT_MESSAGEBUFFER_RECEIVE_FROM_ISR_FAILED : PSF_EVENT_STREAMBUFFER_RECEIVE_FROM_ISR_FAILED, (uint32_t)xStreamBuffer); \ + } \ + } \ + } + +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) */ + +#endif /* (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) */ + +#else /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +/* When recorder is disabled */ +#define vTraceSetQueueName(object, name) +#define vTraceSetSemaphoreName(object, name) +#define vTraceSetMutexName(object, name) +#define vTraceSetEventGroupName(object, name) +#define vTraceSetStreamBufferName(object, name) +#define vTraceSetMessageBufferName(object, name) + +#endif /* (TRC_USE_TRACEALYZER_RECORDER == 1) */ + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_KERNEL_PORT_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcPortDefines.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcPortDefines.h new file mode 100644 index 0000000..d6a4917 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcPortDefines.h @@ -0,0 +1,140 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcPortDefines.h + * + * Some common defines for the trace recorder. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_PORTDEFINES_H +#define TRC_PORTDEFINES_H + +#define TRC_FREE_RUNNING_32BIT_INCR 1 +#define TRC_FREE_RUNNING_32BIT_DECR 2 +#define TRC_OS_TIMER_INCR 3 +#define TRC_OS_TIMER_DECR 4 +#define TRC_CUSTOM_TIMER_INCR 5 +#define TRC_CUSTOM_TIMER_DECR 6 + +/* Start options for vTraceEnable. */ +#define TRC_INIT 0 +#define TRC_START 1 +#define TRC_START_AWAIT_HOST 2 + +/* Command codes for TzCtrl task */ +#define CMD_SET_ACTIVE 1 /* Start (param1 = 1) or Stop (param1 = 0) */ + +/* The final command code, used to validate commands. */ +#define CMD_LAST_COMMAND 1 + +#define TRC_RECORDER_MODE_SNAPSHOT 0 +#define TRC_RECORDER_MODE_STREAMING 1 + +#define TRC_RECORDER_BUFFER_ALLOCATION_STATIC (0x00) +#define TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC (0x01) +#define TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM (0x02) + +/* Filter Groups */ +#define FilterGroup0 (uint16_t)0x0001 +#define FilterGroup1 (uint16_t)0x0002 +#define FilterGroup2 (uint16_t)0x0004 +#define FilterGroup3 (uint16_t)0x0008 +#define FilterGroup4 (uint16_t)0x0010 +#define FilterGroup5 (uint16_t)0x0020 +#define FilterGroup6 (uint16_t)0x0040 +#define FilterGroup7 (uint16_t)0x0080 +#define FilterGroup8 (uint16_t)0x0100 +#define FilterGroup9 (uint16_t)0x0200 +#define FilterGroup10 (uint16_t)0x0400 +#define FilterGroup11 (uint16_t)0x0800 +#define FilterGroup12 (uint16_t)0x1000 +#define FilterGroup13 (uint16_t)0x2000 +#define FilterGroup14 (uint16_t)0x4000 +#define FilterGroup15 (uint16_t)0x8000 + +/****************************************************************************** + * Supported ports + * + * TRC_HARDWARE_PORT_HWIndependent + * A hardware independent fallback option for event timestamping. Provides low + * resolution timestamps based on the OS tick. + * This may be used on the Win32 port, but may also be used on embedded hardware + * platforms. All time durations will be truncated to the OS tick frequency, + * typically 1 KHz. This means that a task or ISR that executes in less than + * 1 ms get an execution time of zero. + * + * TRC_HARDWARE_PORT_APPLICATION_DEFINED + * Allows for defining the port macros in other source code files. + * + * TRC_HARDWARE_PORT_Win32 + * "Accurate" timestamping based on the Windows performance counter for Win32 + * builds. Note that this gives the host machine time, not the kernel time. + * + * Hardware specific ports + * To get accurate timestamping, a hardware timer is necessary. Below are the + * available ports. Some of these are "unofficial", meaning that + * they have not yet been verified by Percepio but have been contributed by + * external developers. They should work, otherwise let us know by emailing + * support@percepio.com. Some work on any OS platform, while other are specific + * to a certain operating system. + *****************************************************************************/ + +/****** Port Name ************************************* Code ** Official ** OS Platform *********/ +#define TRC_HARDWARE_PORT_APPLICATION_DEFINED 98 /* - - */ +#define TRC_HARDWARE_PORT_NOT_SET 99 /* - - */ +#define TRC_HARDWARE_PORT_HWIndependent 0 /* Yes Any */ +#define TRC_HARDWARE_PORT_Win32 1 /* Yes FreeRTOS on Win32 */ +#define TRC_HARDWARE_PORT_Atmel_AT91SAM7 2 /* No Any */ +#define TRC_HARDWARE_PORT_Atmel_UC3A0 3 /* No Any */ +#define TRC_HARDWARE_PORT_ARM_Cortex_M 4 /* Yes Any */ +#define TRC_HARDWARE_PORT_Renesas_RX600 6 /* Yes Any */ +#define TRC_HARDWARE_PORT_MICROCHIP_PIC24_PIC32 7 /* Yes Any */ +#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_TMS570_RM48 8 /* Yes Any */ +#define TRC_HARDWARE_PORT_TEXAS_INSTRUMENTS_MSP430 9 /* No Any */ +#define TRC_HARDWARE_PORT_XILINX_PPC405 11 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_XILINX_PPC440 12 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_XILINX_MICROBLAZE 13 /* No Any */ +#define TRC_HARDWARE_PORT_NXP_LPC210X 14 /* No Any */ +#define TRC_HARDWARE_PORT_ARM_CORTEX_A9 15 /* Yes Any */ +#define TRC_HARDWARE_PORT_POWERPC_Z4 16 /* No FreeRTOS */ +#define TRC_HARDWARE_PORT_Altera_NiosII 17 /* No Any */ +#define TRC_HARDWARE_PORT_PROCESSOR_EXPERT 95 /* No FreeRTOS */ /* << EST */ + +#endif /*TRC_PORTDEFINES_H*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcRecorder.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcRecorder.h new file mode 100644 index 0000000..82042c7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcRecorder.h @@ -0,0 +1,1713 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcRecorder.h + * + * The public API of the trace recorder. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_RECORDER_H +#define TRC_RECORDER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#ifndef __HIWARE__ /* << EST */ + #include +#endif +#include "trcConfig.h" +#include "trcPortDefines.h" + + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) +typedef uint16_t traceString; +typedef uint8_t traceUBChannel; +typedef uint8_t traceObjectClass; + +#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) +typedef uint16_t traceHandle; +#else +typedef uint8_t traceHandle; +#endif + +#include "trcHardwarePort.h" +#include "trcKernelPort.h" + +#endif + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +typedef const char* traceString; +typedef const void* traceHandle; + +#include "trcHardwarePort.h" +#include "trcStreamingPort.h" +#include "trcKernelPort.h" + +#endif + +#if (TRC_USE_TRACEALYZER_RECORDER == 1) + +#define TRACE_GET_LOW16(value) ((uint16_t)((value) & 0x0000FFFF)) +#define TRACE_GET_HIGH16(value) ((uint16_t)(((value) >> 16) & 0x0000FFFF)) +#define TRACE_SET_LOW16(current, value) (((current) & 0xFFFF0000) | (value)) +#define TRACE_SET_HIGH16(current, value) (((current) & 0x0000FFFF) | (((uint32_t)(value)) << 16)) + +/******************************************************************************/ +/*** Common API - both Snapshot and Streaming mode ****************************/ +/******************************************************************************/ + +/****************************************************************************** +* vTraceEnable(int startOption); +* +* Initializes and optionally starts the trace, depending on the start option. +* To use the trace recorder, the startup must call vTraceEnable before any RTOS +* calls are made (including "create" calls). Three start options are provided: +* +* TRC_START: Starts the tracing directly. In snapshot mode this allows for +* starting the trace at any point in your code, assuming vTraceEnable(TRC_INIT) +* has been called in the startup. +* Can also be used for streaming without Tracealyzer control, e.g. to a local +* flash file system (assuming such a "stream port", see trcStreamingPort.h). +* +* TRC_START_AWAIT_HOST: For streaming mode only. Initializes the trace recorder +* if necessary and waits for a Start command from Tracealyzer ("Start Recording" +* button). This call is intentionally blocking! By calling vTraceEnable with +* this option from the startup code, you start tracing at this point and capture +* the early events. +* +* TRC_INIT: Initializes the trace recorder, but does not start the tracing. +* In snapshot mode, this must be followed by a vTraceEnable(TRC_START) sometime +* later. +* +* Usage examples: +* +* Snapshot trace, from startup: +* +* vTraceEnable(TRC_START); +* +* +* Snapshot trace, from a later point: +* +* vTraceEnable(TRC_INIT); +* +* ... +* vTraceEnable(TRC_START); // e.g., in task context, at some relevant event +* +* Streaming trace, from startup: +* +* vTraceEnable(TRC_START_AWAIT_HOST); // Blocks! +* +* +* Streaming trace, from a later point: +* +* vTraceEnable(TRC_INIT); +* +* +******************************************************************************/ +void vTraceEnable(int startOption); + +/****************************************************************************** + * vTracePrintF + * + * Generates "User Events", with formatted text and data, similar to a "printf". + * User Events can be used for very efficient logging from your application code. + * It is very fast since the actual string formatting is done on the host side, + * when the trace is displayed. The execution time is just some microseconds on + * a 32-bit MCU. + * + * User Events are shown as yellow labels in the main trace view of $PNAME. + * + * An advantage of User Events is that data can be plotted in the "User Event + * Signal Plot" view, visualizing any data you log as User Events, discrete + * states or control system signals (e.g. system inputs or outputs). + * + * You may group User Events into User Event Channels. The yellow User Event + * labels show the logged string, preceded by the channel name within brackets. + * + * Example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceRegisterString(). + * + * Example: + * + * traceString adc_uechannel = xTraceRegisterString("ADC User Events"); + * ... + * vTracePrintF(adc_uechannel, + * "ADC channel %d: %d volts", + * ch, adc_reading); + * + * The following format specifiers are supported in both modes: + * %d - signed integer. + * %u - unsigned integer. + * %X - hexadecimal, uppercase. + * %x - hexadecimal, lowercase. + * %s - string (see comment below) + * + * For integer formats (%d, %u, %x, %X) you may also use width and padding. + * If using -42 as data argument, two examples are: + * "%05d" -> "-0042" + * "%5d" -> " -42". + * + * String arguments are supported in both snapshot and streaming, but in streaming + * mode you need to use xTraceRegisterString and use the returned traceString as + * the argument. In snapshot you simply provide a char* as argument. + * + * Snapshot: vTracePrintF(myChn, "my string: %s", str); + * Streaming: vTracePrintF(myChn, "my string: %s", xTraceRegisterString(str)); + * + * In snapshot mode you can specify 8-bit or 16-bit arguments to reduce RAM usage: + * %hd -> 16 bit (h) signed integer (d). + * %bu -> 8 bit (b) unsigned integer (u). + * + * However, in streaming mode all data arguments are assumed to be 32 bit wide. + * Width specifiers (e.g. %hd) are accepted but ignored (%hd treated like %d). + * + * The maximum event size also differs between the modes. In streaming this is + * limited by a maximum payload size of 52 bytes, including format string and + * data arguments. So if using one data argument, the format string is limited + * to 48 byte, etc. If this is exceeded, the format string is truncated and you + * get a warning in Tracealyzer. + * + * In snapshot mode you are limited to maximum 15 arguments, that must not exceed + * 32 bytes in total (not counting the format string). If exceeded, the recorder + * logs an internal error (displayed when opening the trace) and stops recording. + ******************************************************************************/ +void vTracePrintF(traceString chn, const char* fmt, ...); + + /****************************************************************************** +* vTracePrint +* +* A faster version of vTracePrintF, that only allows for logging a string. +* +* Example: +* +* traceString chn = xTraceRegisterString("MyChannel"); +* ... +* vTracePrint(chn, "Hello World!"); +******************************************************************************/ +void vTracePrint(traceString chn, const char* str); + +/******************************************************************************* +* xTraceRegisterString +* +* Register strings in the recorder, e.g. for names of user event channels. +* +* Example: +* myEventHandle = xTraceRegisterString("MyUserEvent"); +* ... +* vTracePrintF(myEventHandle, "My value is: %d", myValue); +******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) +traceString xTraceRegisterString(const char* name); +#else +#define xTraceRegisterString(x) (x) +#endif + +/******************************************************************************* + * vTraceSet...Name(void* object, const char* name) + * + * Parameter object: pointer to the kernel object that shall be named + * Parameter name: the name to set + * + * Kernel-specific functions for setting names of kernel objects, for display in + * Tracealyzer. + ******************************************************************************/ +/* See trcKernelPort.h for details (kernel-specific) */ + +/******************************************************************************* + * xTraceSetISRProperties + * + * Stores a name and priority level for an Interrupt Service Routine, to allow + * for better visualization. Returns a traceHandle used by vTraceStoreISRBegin. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ +traceHandle xTraceSetISRProperties(const char* name, uint8_t priority); + +/******************************************************************************* + * vTraceStoreISRBegin + * + * Registers the beginning of an Interrupt Service Routine, using a traceHandle + * provided by xTraceSetISRProperties. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ +void vTraceStoreISRBegin(traceHandle handle); + +/******************************************************************************* + * vTraceStoreISREnd + * + * Registers the end of an Interrupt Service Routine. + * + * The parameter pendingISR indicates if the interrupt has requested a + * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the + * interrupt is assumed to return to the previous context. + * + * Example: + * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt + * traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder + * ... + * traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(traceHandleIsrTimer1); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ +void vTraceStoreISREnd(int isTaskSwitchRequired); + +/******************************************************************************* + * vTraceInstanceFinishNow + * + * Creates an event that ends the current task instance at this very instant. + * This makes the viewer to splits the current fragment at this point and begin + * a new actor instance, even if no task-switch has occurred. + *****************************************************************************/ +void vTraceInstanceFinishedNow(void); + +/******************************************************************************* + * vTraceInstanceFinishedNext + * + * Marks the current "task instance" as finished on the next kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + *****************************************************************************/ +void vTraceInstanceFinishedNext(void); + +/******************************************************************************* + * xTraceGetLastError + * + * Returns the last error or warning as a string, or NULL if none. + *****************************************************************************/ +const char* xTraceGetLastError(void); + +/******************************************************************************* + * vTraceClearError + * + * Clears any errors. + *****************************************************************************/ +void vTraceClearError(void); + +/******************************************************************************* +* vTraceStop +* +* Stops the recording. Intended for snapshot mode or if streaming without +* Tracealyzer control (e.g., to a device file system). +******************************************************************************/ +void vTraceStop(void); + +/****************************************************************************** +* vTraceSetFrequency +* +* Registers the clock rate of the time source for the event timestamping. +* This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ) +* should be incorrect for your setup, you can override it using this function. +* +* Must be called prior to vTraceEnable, and the time source is assumed to +* have a fixed clock frequency after the startup. +* +* Note that, in snapshot mode, the value is divided by the TRC_HWTC_DIVISOR. +* This is a software "prescaler" that is also applied on the timestamps. +*****************************************************************************/ +void vTraceSetFrequency(uint32_t frequency); + +/******************************************************************************* +* vTraceSetRecorderDataBuffer +* +* The trcConfig.h setting TRC_CFG_RECORDER_BUFFER_ALLOCATION allows for selecting +* custom allocation (TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM), which allows you to +* control where the recorder trace buffer is allocated. +* +* When custom allocation is selected, use TRC_ALLOC_CUSTOM_BUFFER to make the +* allocation (in global context) and then call vTraceSetRecorderDataBuffer to +* register the allocated buffer. This supports both snapshot and streaming, +* and has no effect if using other allocation modes than CUSTOM. +* +* NOTE: vTraceSetRecorderDataBuffer must be called before vTraceEnable. +******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) +void vTraceSetRecorderDataBuffer(void* pRecorderData); +#else +#define vTraceSetRecorderDataBuffer(pRecorderData) +#endif + + +/******************************************************************************* +* TRC_ALLOC_CUSTOM_BUFFER +* +* If using custom allocation of the trace buffer (i.e., your trcConfig.h has the +* setting TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM), this macro allows you to declare +* the trace buffer in a portable way that works both in snapshot and streaming. +* +* This macro has no effect if using another allocation mode, so you can easily +* switch between different recording modes and configurations, using the same +* initialization code. +* +* This translates to a single static allocation, on which you can apply linker +* directives to place it in a particular memory region. +* +* - Snapshot mode: "RecorderDataType " +* +* - Streaming mode: "char []", +* where is defined in trcStreamingConfig.h. +* +* Example: +* +* // GCC example: place myTraceBuffer in section .tz, defined in the .ld file. +* TRC_ALLOC_CUSTOM_BUFFER(myTraceBuffer) __attribute__((section(".tz"))); +* +* int main(void) +* { +* ... +* vTraceSetRecorderDataBuffer(&myTraceBuffer); // Note the "&" +* ... +* vTraceEnable(TRC_INIT); // Initialize the data structure +******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) + #if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + #define TRC_ALLOC_CUSTOM_BUFFER(bufname) RecorderDataType bufname; + #elif (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + #ifdef TRC_CFG_RTT_BUFFER_SIZE_UP /* J-Link RTT */ + #define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Not static in this case, since declared in user code */ + #else + #define TRC_ALLOC_CUSTOM_BUFFER(bufname) char bufname [TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; + #endif + #endif +#else + #define TRC_ALLOC_CUSTOM_BUFFER(bufname) +#endif + +/****************************************************************************** +* xTraceIsRecordingEnabled +* +* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0. +******************************************************************************/ +int xTraceIsRecordingEnabled(void); + +/******************************************************************************* +* vTraceSetFilterGroup +* +* Sets the "filter group" to assign when creating RTOS objects, such as tasks, +* queues, semaphores and mutexes. This together with vTraceSetFilterMask +* allows you to control what events that are recorded, based on the +* objects they refer to. +* +* There are 16 filter groups named FilterGroup0 .. FilterGroup15. +* +* Note: We don't recommend filtering out the Idle task, so make sure to call +* vTraceSetFilterGroup just before initializing the RTOS, in order to assign +* such "default" objects to the right Filter Group (typically group 0). +* +* Example: +* +* // Assign tasks T1 to FilterGroup0 (default) +* +* +* // Assign Q1 and Q2 to FilterGroup1 +* vTraceSetFilterGroup(FilterGroup1); +* +* +* +* // Assigns Q3 to FilterGroup2 +* vTraceSetFilterGroup(FilterGroup2); +* +* +* // Only include FilterGroup0 and FilterGroup2, exclude FilterGroup1 (Q1 and Q2) from the trace +* vTraceSetFilterMask( FilterGroup0 | FilterGroup2 ); +* +* // Assign the default RTOS objects (e.g. Idle task) to FilterGroup0 +* vTraceSetFilterGroup(FilterGroup0); +* +* +* Note that you may define your own names for the filter groups using +* preprocessor definitions, to make the code easier to understand. +* +* Example: +* +* #define BASE FilterGroup0 +* #define USB_EVENTS FilterGroup1 +* #define CAN_EVENTS FilterGroup2 +* +* Note that filtering per event type (regardless of object) is also available +* in trcConfig.h. +******************************************************************************/ +void vTraceSetFilterGroup(uint16_t filterGroup); + +/****************************************************************************** +* vTraceSetFilterMask +* +* Sets the "filter mask" that is used to filter the events by object. This can +* be used to reduce the trace data rate, i.e., if your streaming interface is +* a bottleneck or if you want longer snapshot traces without increasing the +* buffer size. +* +* Note: There are two kinds of filters in the recorder. The other filter type +* excludes all events of certain kinds (e.g., OS ticks). See trcConfig.h. +* +* The filtering is based on bitwise AND with the Filter Group ID, assigned +* to RTOS objects such as tasks, queues, semaphores and mutexes. +* This together with vTraceSetFilterGroup allows you to control what +* events that are recorded, based on the objects they refer to. +* +* See example for vTraceSetFilterGroup. +******************************************************************************/ +void vTraceSetFilterMask(uint16_t filterMask); + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + +/******************************************************************************/ +/*** Extended API for Snapshot mode *******************************************/ +/******************************************************************************/ + +/****************************************************************************** +* TRACE_STOP_HOOK - Hook Pointer Data Type +* +* Declares a data type for a call back function that will be invoked whenever +* the recorder is stopped. +* +* Snapshot mode only! +******************************************************************************/ +typedef void(*TRACE_STOP_HOOK)(void); + +/******************************************************************************* +* vTraceStopHookPtr +* +* Points to a call back function that is called from vTraceStop(). +* +* Snapshot mode only! +******************************************************************************/ +extern TRACE_STOP_HOOK vTraceStopHookPtr; + +/******************************************************************************* +* vTraceSetStopHook +* +* Sets a function to be called when the recorder is stopped. +* +* Snapshot mode only! +******************************************************************************/ +void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction); + +/******************************************************************************* +* uiTraceStart +* +* [DEPRECATED] Use vTraceEnable instead. +* +* Starts the recorder. The recorder will not be started if an error has been +* indicated using prvTraceError, e.g. if any of the Nx constants in +* trcSnapshotConfig.h has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc). +* +* Returns 1 if the recorder was started successfully. +* Returns 0 if the recorder start was prevented due to a previous internal +* error. In that case, check xTraceGetLastError to get the error message. +* Any error message is also presented when opening a trace file. +* +* Snapshot mode only! +******************************************************************************/ +uint32_t uiTraceStart(void); + +/******************************************************************************* +* vTraceStart +* +* [DEPRECATED] Use vTraceEnable instead. +* +* Starts the recorder. The recorder will not be started if an error has been +* indicated using prvTraceError, e.g. if any of the Nx constants in +* trcSnapshotConfig.h has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc). +* +* Snapshot mode only! +******************************************************************************/ +void vTraceStart(void); + +/******************************************************************************* +* vTraceClear +* +* Resets the recorder. Only necessary if a restart is desired - this is not +* needed in the startup initialization. +* +* Snapshot mode only! +******************************************************************************/ +void vTraceClear(void); + + +/*****************************************************************************/ +/*** INTERNAL SNAPSHOT FUNCTIONS *********************************************/ +/*****************************************************************************/ + +#define TRC_UNUSED + +#ifndef TRC_CFG_INCLUDE_OBJECT_DELETE +#define TRC_CFG_INCLUDE_OBJECT_DELETE 0 +#endif + +#ifndef TRC_CFG_INCLUDE_READY_EVENTS +#define TRC_CFG_INCLUDE_READY_EVENTS 1 +#endif + +#ifndef TRC_CFG_INCLUDE_OSTICK_EVENTS +#define TRC_CFG_INCLUDE_OSTICK_EVENTS 0 +#endif + +/* This macro will create a task in the object table */ +#undef trcKERNEL_HOOKS_TASK_CREATE +#define trcKERNEL_HOOKS_TASK_CREATE(SERVICE, CLASS, pxTCB) \ + TRACE_SET_TASK_NUMBER(pxTCB) \ + TRACE_SET_TASK_FILTER(pxTCB, CurrentFilterGroup); \ + prvTraceSetObjectName(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_NAME(pxTCB)); \ + prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \ + prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); + +/* This macro will remove the task and store it in the event buffer */ +#undef trcKERNEL_HOOKS_TASK_DELETE +#define trcKERNEL_HOOKS_TASK_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, pxTCB) \ + prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \ + prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \ + prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_CLASS_TASK); \ + prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TRACE_GET_TASK_PRIORITY(pxTCB)); \ + prvTraceSetObjectState(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), TASK_STATE_INSTANCE_NOT_ACTIVE); \ + prvTraceFreeObjectHandle(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); + + +/* This macro will setup a task in the object table */ +#undef trcKERNEL_HOOKS_OBJECT_CREATE +#define trcKERNEL_HOOKS_OBJECT_CREATE(SERVICE, CLASS, pxObject)\ + TRACE_SET_OBJECT_NUMBER(CLASS, pxObject);\ + TRACE_SET_OBJECT_FILTER(CLASS, pxObject, CurrentFilterGroup); \ + prvMarkObjectAsUsed(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject));\ + prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \ + prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), 0); + +/* This macro will remove the object and store it in the event buffer */ +#undef trcKERNEL_HOOKS_OBJECT_DELETE +#define trcKERNEL_HOOKS_OBJECT_DELETE(SERVICE, SERVICE_NAME, SERVICE_PROP, CLASS, pxObject) \ + prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); \ + prvTraceStoreObjectNameOnCloseEvent(SERVICE_NAME, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \ + prvTraceStoreObjectPropertiesOnCloseEvent(SERVICE_PROP, TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject)); \ + prvTraceFreeObjectHandle(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ +#undef trcKERNEL_HOOKS_KERNEL_SERVICE +#define trcKERNEL_HOOKS_KERNEL_SERVICE(SERVICE, CLASS, pxObject) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ + prvTraceStoreKernelCall(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject)); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ +#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM +#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_PARAM(SERVICE, CLASS, pxObject, param) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_OBJECT_FILTER(CLASS, pxObject) & CurrentFilterMask) \ + prvTraceStoreKernelCallWithParam(SERVICE, TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint32_t)param); + +/* This macro will create a call to a kernel service with a certain result, with an object as parameter */ +#undef trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY +#define trcKERNEL_HOOKS_KERNEL_SERVICE_WITH_NUMERIC_PARAM_ONLY(SERVICE, param) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, (uint32_t)param); + +/* This macro will set the state for an object */ +#undef trcKERNEL_HOOKS_SET_OBJECT_STATE +#define trcKERNEL_HOOKS_SET_OBJECT_STATE(CLASS, pxObject, STATE) \ + prvTraceSetObjectState(TRACE_GET_OBJECT_TRACE_CLASS(CLASS, pxObject), TRACE_GET_OBJECT_NUMBER(CLASS, pxObject), (uint8_t)STATE); + +/* This macro will flag a certain task as a finished instance */ +#undef trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED +#define trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED() \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + prvTraceSetTaskInstanceFinished(TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK())); + +#if (TRC_CFG_INCLUDE_READY_EVENTS == 1) +/* This macro will create an event to indicate that a task became Ready */ +#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE +#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreTaskReady(TRACE_GET_TASK_NUMBER(pxTCB)); +#else /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ +#undef trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE +#define trcKERNEL_HOOKS_MOVED_TASK_TO_READY_STATE(pxTCB) +#endif /*(TRC_CFG_INCLUDE_READY_EVENTS == 1)*/ + +/* This macro will update the internal tick counter and call prvTracePortGetTimeStamp(0) to update the internal counters */ +#undef trcKERNEL_HOOKS_INCREMENT_TICK +#define trcKERNEL_HOOKS_INCREMENT_TICK() \ + { \ + extern uint32_t uiTraceTickCount; \ + uiTraceTickCount++; \ + prvTracePortGetTimeStamp(0); \ + } + +#if (TRC_CFG_INCLUDE_OSTICK_EVENTS == 1) +/* This macro will create an event indicating that the OS tick count has increased */ +#undef trcKERNEL_HOOKS_NEW_TIME +#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) \ + prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); +#else /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ +#undef trcKERNEL_HOOKS_NEW_TIME +#define trcKERNEL_HOOKS_NEW_TIME(SERVICE, xValue) +#endif /*(TRC_CFG_INCLUDE_OSTICK_EVENTS == 1)*/ + +/* This macro will create a task switch event to the currently executing task */ +#undef trcKERNEL_HOOKS_TASK_SWITCH +#define trcKERNEL_HOOKS_TASK_SWITCH( pxTCB ) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreTaskswitch(TRACE_GET_TASK_NUMBER(pxTCB)); + +/* This macro will create an event to indicate that the task has been suspended */ +#undef trcKERNEL_HOOKS_TASK_SUSPEND +#define trcKERNEL_HOOKS_TASK_SUSPEND(SERVICE, pxTCB) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); \ + prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); + +/* This macro will create an event to indicate that a task has called a wait/delay function */ +#undef trcKERNEL_HOOKS_TASK_DELAY +#define trcKERNEL_HOOKS_TASK_DELAY(SERVICE, pxTCB, xValue) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + { \ + prvTraceStoreKernelCallWithNumericParamOnly(SERVICE, xValue); \ + prvTraceSetTaskInstanceFinished((uint8_t)TRACE_GET_TASK_NUMBER(pxTCB)); \ + } + +/* This macro will create an event to indicate that a task has gotten its priority changed */ +#undef trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE +#define trcKERNEL_HOOKS_TASK_PRIORITY_CHANGE(SERVICE, pxTCB, uxNewPriority) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + { \ + prvTraceStoreKernelCallWithParam(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), prvTraceGetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)));\ + prvTraceSetPriorityProperty(TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB), (uint8_t)uxNewPriority); \ + } + +/* This macro will create an event to indicate that the task has been resumed */ +#undef trcKERNEL_HOOKS_TASK_RESUME +#define trcKERNEL_HOOKS_TASK_RESUME(SERVICE, pxTCB) \ + if (TRACE_GET_TASK_FILTER(TRACE_GET_CURRENT_TASK()) & CurrentFilterMask) \ + if (TRACE_GET_TASK_FILTER(pxTCB) & CurrentFilterMask) \ + prvTraceStoreKernelCall(SERVICE, TRACE_CLASS_TASK, TRACE_GET_TASK_NUMBER(pxTCB)); + +#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 + void prvTraceSetReadyEventsEnabled(int status); + void prvTraceStoreTaskReady(traceHandle handle); +#else + #define prvTraceSetReadyEventsEnabled(status) +#endif + +void prvTraceStoreLowPower(uint32_t flag); + +void prvTraceStoreTaskswitch(traceHandle task_handle); + + +#if (TRC_CFG_SCHEDULING_ONLY == 0) + +void prvTraceStoreKernelCall(uint32_t eventcode, traceObjectClass objectClass, uint32_t byteParam); + +void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param); + +void prvTraceStoreKernelCallWithParam(uint32_t evtcode, traceObjectClass objectClass, + uint32_t objectNumber, uint32_t param); +#else + +#define prvTraceStoreKernelCall(eventcode, objectClass, byteParam) {} +#define prvTraceStoreKernelCallWithNumericParamOnly(evtcode, param) {} +#define prvTraceStoreKernelCallWithParam(evtcode, objectClass, objectNumber, param) {} + +#endif + +void prvTraceSetTaskInstanceFinished(traceHandle handle); + +void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value); + +uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id); + +void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value); + +void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle); + +void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, + traceObjectClass objectclass); + +void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, + traceObjectClass objectclass); + +/* Internal constants for task state */ +#define TASK_STATE_INSTANCE_NOT_ACTIVE 0 +#define TASK_STATE_INSTANCE_ACTIVE 1 + + +#if (TRC_CFG_INCLUDE_ISR_TRACING == 0) + +#undef vTraceSetISRProperties +#define vTraceSetISRProperties(handle, name, priority) + +#undef vTraceStoreISRBegin +#define vTraceStoreISRBegin(x) (void)x + +#undef vTraceStoreISREnd +#define vTraceStoreISREnd(x) (void)x + +#undef xTraceSetISRProperties +#define xTraceSetISRProperties(name, priority) 0 + +#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ + +/******************************************************************************* + * xTraceGetTraceBuffer + * + * Returns a pointer to the recorder data structure. Use this together with + * uiTraceGetTraceBufferSize if you wish to implement an own store/upload + * solution, e.g., in case a debugger connection is not available for uploading + * the data. + ******************************************************************************/ +void* xTraceGetTraceBuffer(void); + +/******************************************************************************* + * uiTraceGetTraceBufferSize + * + * Gets the size of the recorder data structure. For use together with + * vTraceGetTraceBuffer if you wish to implement an own store/upload solution, + * e.g., in case a debugger connection is not available for uploading the data. + ******************************************************************************/ +uint32_t uiTraceGetTraceBufferSize(void); + +#if (TRC_CFG_SCHEDULING_ONLY == 1) +#undef TRC_CFG_INCLUDE_USER_EVENTS +#define TRC_CFG_INCLUDE_USER_EVENTS 0 +#endif /*(TRC_CFG_SCHEDULING_ONLY == 1)*/ + +#if ((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0)) + +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) +traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatStr); +void vTraceUBData(traceUBChannel channel, ...); +void vTraceUBEvent(traceUBChannel channel); +#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/ + +#else /*((TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0))*/ + +#undef vTracePrint +#define vTracePrint(chn, ...) (void)chn +#undef vTracePrintF +#define vTracePrintF(chn, ...) (void)chn +#undef xTraceRegisterString +#define xTraceRegisterString(x) 0; (void)x; +#undef xTraceRegisterChannelFormat +#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0 +#undef vTraceUBData +#define vTraceUBData(label, ...) {} +#undef vTraceChannelPrint +#define vTraceChannelPrint(label) {} + +#endif /*(TRC_CFG_INCLUDE_USER_EVENTS == 1)*/ + +#define NEventCodes 0x100 + +/* Our local critical sections for the recorder */ +#define trcCRITICAL_SECTION_BEGIN() {TRACE_ENTER_CRITICAL_SECTION(); recorder_busy++;} +#define trcCRITICAL_SECTION_END() {recorder_busy--; TRACE_EXIT_CRITICAL_SECTION();} + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) + #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY TRACE_ALLOC_CRITICAL_SECTION + #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_BEGIN + #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY trcCRITICAL_SECTION_END +#else + #define trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY() {} + #define trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY() recorder_busy++; + #define trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY() recorder_busy--; +#endif + +/****************************************************************************** + * ObjectHandleStack + * This data-structure is used to provide a mechanism for 1-byte trace object + * handles. This way, only 1 byte is necessary instead of 4 bytes (a pointer) + * when storing a reference to an object. This allows for up to 255 objects of + * each object class active at any given moment. There can be more "historic" + * objects, that have been deleted - that number is only limited by the size of + * the symbol table. + * + * Note that handle zero (0) is not used, it is a code for an invalid handle. + * + * This data structure keeps track of the FREE handles, not the handles in use. + * This data structure contains one stack per object class. When a handle is + * allocated to an object, the next free handle is popped from the stack. When + * a handle is released (on object delete), it is pushed back on the stack. + * Note that there is no initialization code that pushed the free handles + * initially, that is not necessary due to the following optimization: + * + * The stack of handles (objectHandles) is initially all zeros. Since zero + * is not a valid handle, that is a signal of additional handles needed. + * If a zero is received when popping a new handle, it is replaced by the + * index of the popped handle instead. + *****************************************************************************/ +typedef struct +{ + /* For each object class, the index of the next handle to allocate */ + uint16_t indexOfNextAvailableHandle[ TRACE_NCLASSES ]; + + /* The lowest index of this class (constant) */ + uint16_t lowestIndexOfClass[ TRACE_NCLASSES ]; + + /* The highest index of this class (constant) */ + uint16_t highestIndexOfClass[ TRACE_NCLASSES ]; + + /* The highest use count for this class (for statistics) */ + uint16_t handleCountWaterMarksOfClass[ TRACE_NCLASSES ]; + + /* The free object handles - a set of stacks within this array */ + traceHandle objectHandles[ TRACE_KERNEL_OBJECT_COUNT ]; + +} objectHandleStackType; + +extern objectHandleStackType objectHandleStacks; + +/****************************************************************************** + * Object Property Table + * The Object Table contains name and other properties of the objects (tasks, + * queues, mutexes, etc). The below data structures defines the properties of + * each object class and are used to cast the byte buffer into a cleaner format. + * + * The values in the object table are continuously overwritten and always + * represent the current state. If a property is changed during runtime, the OLD + * value should be stored in the trace buffer, not the new value (since the new + * value is found in the Object Property Table). + * + * For close events this mechanism is the old names are stored in the symbol + * table), for "priority set" (the old priority is stored in the event data) + * and for "isActive", where the value decides if the task switch event type + * should be "new" or "resume". + ******************************************************************************/ + +typedef struct +{ + /* = NCLASSES */ + uint32_t NumberOfObjectClasses; + + uint32_t ObjectPropertyTableSizeInBytes; + + /* This is used to calculate the index in the dynamic object table + (handle - 1 - nofStaticObjects = index)*/ +#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) + traceHandle NumberOfObjectsPerClass[2*((TRACE_NCLASSES+1)/2)]; +#else + traceHandle NumberOfObjectsPerClass[4*((TRACE_NCLASSES+3)/4)]; +#endif + + /* Allocation size rounded up to the closest multiple of 4 */ + uint8_t NameLengthPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; + + uint8_t TotalPropertyBytesPerClass[ 4*((TRACE_NCLASSES+3)/4) ]; + + /* Allocation size rounded up to the closest multiple of 2 */ + uint16_t StartIndexOfClass[ 2*((TRACE_NCLASSES+1)/2) ]; + + /* The actual handles issued, should be Initiated to all zeros */ + uint8_t objbytes[ 4*((TRACE_OBJECT_TABLE_SIZE+3)/4) ]; +} ObjectPropertyTableType; + +/* Symbol table data structure */ +typedef struct +{ + /* = SYMBOL_HISTORY_TABLE_SIZE_IN_BYTES */ + uint32_t symTableSize; + + /* Entry 0 is reserved. Any reference to entry 0 implies NULL*/ + uint32_t nextFreeSymbolIndex; + + /* Size rounded up to closest multiple of 4, to avoid alignment issues*/ + uint8_t symbytes[4*((TRC_CFG_SYMBOL_TABLE_SIZE+3)/4)]; + + /* Used for lookups - Up to 64 linked lists within the symbol table + connecting all entries with the same 6 bit checksum. + This field holds the current list heads. Should be initiated to zeros */ + uint16_t latestEntryOfChecksum[64]; +} symbolTableType; + + +/******************************************************************************* + * The data structures of the different events, all 4 bytes long + ******************************************************************************/ + +typedef struct +{ + uint8_t type; + uint8_t objHandle; + uint16_t dts; /* differential timestamp - time since last event */ +} TSEvent, TREvent; + +typedef struct +{ + uint8_t type; + uint8_t dummy; + uint16_t dts; /* differential timestamp - time since last event */ +} LPEvent; + +typedef struct +{ + uint8_t type; + uint8_t objHandle; + uint16_t dts; /* differential timestamp - time since last event */ +} KernelCall; + +typedef struct +{ + uint8_t type; + uint8_t objHandle; + uint8_t param; + uint8_t dts; /* differential timestamp - time since last event */ +} KernelCallWithParamAndHandle; + +typedef struct +{ + uint8_t type; + uint8_t dts; /* differential timestamp - time since last event */ + uint16_t param; +} KernelCallWithParam16; + +typedef struct +{ + uint8_t type; + uint8_t objHandle; /* the handle of the closed object */ + uint16_t symbolIndex; /* the name of the closed object */ +} ObjCloseNameEvent; + +typedef struct +{ + uint8_t type; + uint8_t arg1; + uint8_t arg2; + uint8_t arg3; +} ObjClosePropEvent; + +typedef struct +{ + uint8_t type; + uint8_t unused1; + uint8_t unused2; + uint8_t dts; +} TaskInstanceStatusEvent; + +typedef struct +{ + uint8_t type; + uint8_t dts; + uint16_t payload; /* the name of the user event */ +} UserEvent; + +typedef struct +{ + uint8_t type; + + /* 8 bits extra for storing DTS, if it does not fit in ordinary event + (this one is always MSB if used) */ + uint8_t xts_8; + + /* 16 bits extra for storing DTS, if it does not fit in ordinary event. */ + uint16_t xts_16; +} XTSEvent; + +typedef struct +{ + uint8_t type; + + uint8_t xps_8; + uint16_t xps_16; +} XPSEvent; + +typedef struct{ + uint8_t type; + uint8_t dts; + uint16_t size; +} MemEventSize; + +typedef struct{ + uint8_t type; + uint8_t addr_high; + uint16_t addr_low; +} MemEventAddr; + +/******************************************************************************* + * The separate user event buffer structure. Can be enabled in trcConfig.h. + ******************************************************************************/ + +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) +typedef struct +{ + traceString name; + traceString defaultFormat; +} ChannelFormatPair; + +typedef struct +{ + uint16_t bufferID; + uint16_t version; + uint32_t wraparoundCounter; + uint32_t numberOfSlots; + uint32_t nextSlotToWrite; + uint8_t numberOfChannels; + uint8_t padding1; + uint8_t padding2; + uint8_t padding3; + ChannelFormatPair channels[TRC_CFG_UB_CHANNELS+1]; + uint8_t channelBuffer[(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + 3) & 0xFFFFFFFC]; /* 1 byte per slot, with padding for 4 byte alignment */ + uint8_t dataBuffer[TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE * 4]; /* 4 bytes per slot */ + +} UserEventBuffer; +#endif + +/******************************************************************************* + * The main data structure, read by Tracealyzer from the RAM dump + ******************************************************************************/ + +typedef struct +{ + volatile uint8_t startmarker0; /* Volatile is important, see init code. */ + volatile uint8_t startmarker1; + volatile uint8_t startmarker2; + volatile uint8_t startmarker3; + volatile uint8_t startmarker4; + volatile uint8_t startmarker5; + volatile uint8_t startmarker6; + volatile uint8_t startmarker7; + volatile uint8_t startmarker8; + volatile uint8_t startmarker9; + volatile uint8_t startmarker10; + volatile uint8_t startmarker11; + + /* Used to determine Kernel and Endianess */ + uint16_t version; + + /* Currently 5 */ + uint8_t minor_version; + + /* This should be 0 if lower IRQ priority values implies higher priority + levels, such as on ARM Cortex M. If the opposite scheme is used, i.e., + if higher IRQ priority values means higher priority, this should be 1. */ + uint8_t irq_priority_order; + + /* sizeof(RecorderDataType) - just for control */ + uint32_t filesize; + + /* Current number of events recorded */ + uint32_t numEvents; + + /* The buffer size, in number of event records */ + uint32_t maxEvents; + + /* The event buffer index, where to write the next event */ + uint32_t nextFreeIndex; + + /* 1 if the buffer is full, 0 otherwise */ + uint32_t bufferIsFull; + + /* The frequency of the clock/timer/counter used as time base */ + uint32_t frequency; + + /* The absolute timestamp of the last stored event, in the native + timebase, modulo frequency! */ + uint32_t absTimeLastEvent; + + /* The number of seconds in total - lasts for 136 years */ + uint32_t absTimeLastEventSecond; + + /* 1 if the recorder has been started, 0 if not yet started or stopped. + This is a 32 bit variable due to alignment issues. */ + uint32_t recorderActive; + + /* If > 0, tells the maximum time between two traced ISRs that execute + back-to-back. If the time between vTraceStoreISREnd and a directly + following vTraceISRBegin is above isrTailchainingThreshold, we assume a + return to the previous context in between the ISRs, otherwise we assume + the have executed back-to-back and don't show any fragment of the previous + context in between. */ + uint32_t isrTailchainingThreshold; + + /* Not used, remains for compatibility and future use */ + uint8_t notused[24]; + + /* The amount of heap memory remaining at the last malloc or free event */ + uint32_t heapMemUsage; + + /* 0xF0F0F0F0 - for control only */ + int32_t debugMarker0; + + /* Set to value of TRC_CFG_USE_16BIT_OBJECT_HANDLES */ + uint32_t isUsing16bitHandles; + + /* The Object Property Table holds information about currently active + tasks, queues, and other recorded objects. This is updated on each + create call and includes object name and other properties. */ + ObjectPropertyTableType ObjectPropertyTable; + + /* 0xF1F1F1F1 - for control only */ + int32_t debugMarker1; + + /* The Symbol Table stores strings for User Events and is also used to + store names of deleted objects, which still may be in the trace but no + longer are available. */ + symbolTableType SymbolTable; + + /* For inclusion of float support, and for endian detection of floats. + The value should be (float)1 or (uint32_t)0 */ +#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1) + float exampleFloatEncoding; +#else + uint32_t exampleFloatEncoding; +#endif + /* This is non-zero if an internal error occurred in the recorder, e.g., if + one of the Nxxx constants was too small. The systemInfo string will then + contain an error message that is displayed when attempting to view the + trace file. */ + uint32_t internalErrorOccured; + + /* 0xF2F2F2F2 - for control only */ + int32_t debugMarker2; + + /* Error messages from the recorder. */ + char systemInfo[TRC_CFG_TRACE_DESCRIPTION_MAX_LENGTH]; /* << EST */ + + /* 0xF3F3F3F3 - for control only */ + int32_t debugMarker3; + + /* The event data, in 4-byte records */ + uint8_t eventData[ TRC_CFG_EVENT_BUFFER_SIZE * 4 ]; + +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) + UserEventBuffer userEventBuffer; +#endif + + /* This should always be 0 */ + uint32_t endOfSecondaryBlocks; + + uint8_t endmarker0; + uint8_t endmarker1; + uint8_t endmarker2; + uint8_t endmarker3; + uint8_t endmarker4; + uint8_t endmarker5; + uint8_t endmarker6; + uint8_t endmarker7; + uint8_t endmarker8; + uint8_t endmarker9; + uint8_t endmarker10; + uint8_t endmarker11; +} RecorderDataType; + +extern RecorderDataType* RecorderDataPtr; + +/* Internal functions */ + +/* Signal an error. */ +void prvTraceError(const char* msg); + +/******************************************************************************* + * prvTracePortGetTimeStamp + * + * Returns the current time based on the HWTC macros which provide a hardware + * isolation layer towards the hardware timer/counter. + * + * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue + * or the trace recorder library. Typically you should not need to change + * the code of prvTracePortGetTimeStamp if using the HWTC macros. + * + ******************************************************************************/ +void prvTracePortGetTimeStamp(uint32_t *puiTimestamp); + +traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass); + +void prvTraceFreeObjectHandle(traceObjectClass objectclass, + traceHandle handle); + +/* Private function. Use the public functions in trcKernelPort.h */ +void prvTraceSetObjectName(traceObjectClass objectclass, + traceHandle handle, + const char* name); + +/* Internal macros */ + +#define TRACE_PROPERTY_NAME_GET(objectclass, objecthandle) \ +(const char*)(& RecorderDataPtr->ObjectPropertyTable.objbytes \ +[uiIndexOfObject(objecthandle, objectclass)]) + +#define TRACE_PROPERTY_OBJECT_STATE(objectclass, handle) \ +RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \ ++ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass]] + +#define TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle) \ +RecorderDataPtr->ObjectPropertyTable.objbytes[uiIndexOfObject(handle, objectclass) \ ++ RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[objectclass] + 1] + +/* DEBUG ASSERTS */ +#if defined TRC_CFG_USE_TRACE_ASSERT && TRC_CFG_USE_TRACE_ASSERT != 0 +#define TRACE_ASSERT(eval, msg, defRetVal) \ +if (!(eval)) \ +{ \ + prvTraceError("TRACE_ASSERT: " msg); \ + return defRetVal; \ +} +#else +#define TRACE_ASSERT(eval, msg, defRetVal) +#endif + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +/****************************************************************************** + * Default values for STREAM PORT macros + * + * As a normal user, this is nothing you don't need to bother about. This is + * only important if you want to define your own custom streaming interface. + * + * You may override these in your own trcStreamingPort.h to create a custom + * stream port, and thereby stream the trace on any host-target interface. + * These default values are suitable for most cases, except the J-Link port. + ******************************************************************************/ + +/****************************************************************************** + * TRC_STREAM_PORT_USE_INTERNAL_BUFFER + * + * There are two kinds of stream ports, those that store the event to the + * internal buffer (with periodic flushing by the TzCtrl task) and those that + * write directly to the streaming interface. Most stream ports use the + * recorder's internal buffer, except for the SEGGER J-Link port (also uses a + * RAM buffer, but one defined in the SEGGER code). + * + * If the stream port (trcStreamingPort.h) defines this as zero (0), it is + * expected to transmit the data directly using TRC_STREAM_PORT_COMMIT_EVENT. + * Otherwise it is expected that the trace data is stored in the internal buffer + * and the TzCtrl task will then send the buffer pages when they become full. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_USE_INTERNAL_BUFFER +#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 1 +#endif + + /****************************************************************************** + * TRC_STREAM_PORT_ON_TRACE_BEGIN + * + * Defining any actions needed in the stream port when the recording is activated. + *******************************************************************************/ +#ifndef TRC_STREAM_PORT_ON_TRACE_BEGIN + #define TRC_STREAM_PORT_ON_TRACE_BEGIN() /* Do nothing */ +#endif + + /****************************************************************************** + * TRC_STREAM_PORT_ON_TRACE_BEGIN + * + * Defining any actions needed in the stream port when the tracing stops. + * Empty by default. + *******************************************************************************/ +#ifndef TRC_STREAM_PORT_ON_TRACE_END +#define TRC_STREAM_PORT_ON_TRACE_END() /* Do nothing */ +#endif + + /****************************************************************************** + * TRC_STREAM_PORT_ALLOCATE_EVENT + * + * This macro is used to allocate memory for each event record, just before + * assigning the record fields. + * Depending on "TRC_STREAM_PORT_USE_INTERNAL_BUFFER", this either allocates + * space in the paged event buffer, or on the local stack. In the latter case, + * the COMMIT event is used to write the data to the streaming interface. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_ALLOCATE_EVENT +#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + #define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type* _ptrData; _ptrData = (_type*)prvPagedEventBufferGetWritePointer(_size); +#else + #define TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) _type _tmpArray[_size / sizeof(_type)]; _type* _ptrData = _tmpArray; +#endif +#endif + + /****************************************************************************** + * TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT + * + * This macro is used to allocate memory for each event record, just before + * assigning the record fields. + * This has the same purpose as TRC_STREAM_PORT_ALLOCATE_EVENT and by default + * it has the same definition as TRC_STREAM_PORT_ALLOCATE_EVENT. This is used + * for events carrying variable-sized payload, such as strings. + * In the SEGGER RTT port, we need this in order to make a worst-case + * allocation on the stack. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT +#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + #define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) TRC_STREAM_PORT_ALLOCATE_EVENT(_type, _ptrData, _size) /* We do the same thing as for non-dynamic event sizes */ +#else + #define TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(_type, _ptrData, _size) _type _tmpArray[sizeof(largestEventType) / sizeof(_type)]; _type* _ptrData = _tmpArray; +#endif +#endif + + /****************************************************************************** + * TRC_STREAM_PORT_COMMIT_EVENT + * + * The COMMIT macro is used to write a single event record directly to the + * streaming inteface, without first storing the event in the internal buffer. + * This is currently only used in the SEGGER J-Link RTT port. + * + * This relies on the TRC_STREAM_PORT_WRITE_DATA macro, defined in by the + * stream port in trcStreamingPort.h. The COMMIT macro calls + * prvTraceWarning(TRC_STREAM_PORT_WRITE_DATA) if a non-zero value is returned + * from TRC_STREAM_PORT_WRITE_DATA. If zero (0) is returned, it is assumed + * that all data was successfully written. + * + * In ports using the internal buffer, this macro has no purpose as the events + * are written to the internal buffer instead. They are then flushed to the + * streaming interface in the TzCtrl task using TRC_STREAM_PORT_WRITE_DATA. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_COMMIT_EVENT +#if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + #define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) /* Not used */ +#else + #define TRC_STREAM_PORT_COMMIT_EVENT(_ptrData, _size) \ + { \ + if (TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, 0) != 0)\ + prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE); \ + } +#endif +#endif + +/****************************************************************************** + * TRC_STREAM_PORT_READ_DATA (defined in trcStreamingPort.h) + * + * Defining how to read data from host (commands from Tracealyzer). + * + * If there is no direct interface to host (e.g., if streaming to a file + * system) this should be defined as 0. Instead use vTraceEnable(TRC_START) and + * vTraceStop() to control the recording from target. + * + * Parameters: + * + * - _ptrData: a pointer to a data buffer, where the received data shall be + * stored (TracealyzerCommandType*). + * + * - _size: the number of bytes to read (int). + * + * - _ptrBytesRead: a pointer to an integer (int), that should be assigned + * with the number of bytes that was received. + * + * Example: + * + * int32_t myRead(void* ptrData, uint32_t size, int32_t* ptrBytesRead); + * + * #define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) \ + * myRead(_ptrData, _size, _ptrBytesRead) + * + * Your "myRead" function should return 0 if successful, i.e. if at least some + * bytes were received. A non-zero value should be returned if the streaming + * interface returned an error (e.g. a closed socket), which results in the + * recorder calling prvTraceWarning with the error code + * PSF_WARNING_STREAM_PORT_WRITE. + * + * If developing your own custom stream port and using the default internal + * buffer, it is important that the _ptrBytesRead parameter is assigned + * correctly by "myRead", i.e. with the number of bytes actually written. + * Otherwise the data stream may get out of sync in case the streaming interface + * can't swallow all data at once. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_READ_DATA +#error "No definition for TRC_STREAM_PORT_READ_DATA (should be in trcStreamingPort.h)" +#endif + +/****************************************************************************** + * TRC_STREAM_PORT_WRITE_DATA (defined in trcStreamingPort.h) + * + * Defining how to write trace data to the streaming interface. + * + * Parameters: + * + * - _ptrData: a pointer (void*) to the data to write. + * + * - _size: the number of bytes to write (uint32_t). + * + * - _ptrBytesWritten: a pointer to an integer (int32_t), that should be + * assigned with the number of bytes actually written. + * + * Example: + * + * int32_t myWrite(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); + * + * #define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) \ + * myWrite(_ptrData, _size, _ptrBytesWritten) + * + * Your "myWrite" function should return 0 if successful, i.e. if at least some + * bytes were sent. A non-zero value should be returned if the streaming interface + * returned an error (e.g. a closed socket), which results in the recorder calling + * prvTraceWarning with the error code PSF_WARNING_STREAM_PORT_WRITE. + * + * If developing your own custom stream port and using the default internal + * buffer, it is important that the _ptrBytesWritten parameter is assigned + * correctly by "myWrite", i.e. with the number of bytes actually written. + * Otherwise the data stream may get out of sync in case the streaming interface + * can't swallow all data at once. + * + * Assuming TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 1 (default), the TzCtrl task + * will use this macro to send one buffer page at a time. In case all data can't + * be written at once (if _ptrBytesWritten is less than _size), the TzCtrl task + * is smart enough to make repeated calls (with updated parameters) in order to + * send the remaining data. + * + * However, if TRC_STREAM_PORT_USE_INTERNAL_BUFFER is 0, this is used from the + * COMMIT macro, directly in the "event functions". In that case, the + * _ptrBytesWritten parameter will be NULL and should be ignored by the write + * function. In this case, it is assumed that all data can be sent in a single + * call, otherwise the write function should return a non-zero error code. + ******************************************************************************/ +#ifndef TRC_STREAM_PORT_WRITE_DATA +#error "No definition for TRC_STREAM_PORT_WRITE_DATA (should be in trcStreamingPort.h)" +#endif + +/****************************************************************************** +* Data structure declaration, depending on TRC_CFG_RECORDER_BUFFER_ALLOCATION +*******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) + + /* Static allocation. */ + + /* If not defined in trcStreamingPort.h */ + #ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS + #define TRC_STREAM_PORT_ALLOCATE_FIELDS() \ + char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; + extern char _TzTraceData[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; + #endif + + /* If not defined in trcStreamingPort.h */ + #ifndef TRC_STREAM_PORT_MALLOC + #define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ + #endif +#else + /* For Dynamic or Custom Allocation mode */ + + /* If not defined in trcStreamingPort.h */ + #ifndef TRC_STREAM_PORT_ALLOCATE_FIELDS + #define TRC_STREAM_PORT_ALLOCATE_FIELDS() char* _TzTraceData = NULL; + extern char* _TzTraceData; + #endif + + /* If not defined in trcStreamingPort.h */ + #ifndef TRC_STREAM_PORT_MALLOC + #if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC) + #define TRC_STREAM_PORT_MALLOC() \ + _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE); + extern char* _TzTraceData; + #else + #define TRC_STREAM_PORT_MALLOC() /* Custom allocation. Not used. */ + #endif + #endif +#endif + +#ifndef TRC_STREAM_PORT_INIT + #define TRC_STREAM_PORT_INIT() \ + TRC_STREAM_PORT_MALLOC(); /* Empty if static allocation mode */ \ + prvPagedEventBufferInit(_TzTraceData); +#endif + + +/* Signal an error. */ +void prvTraceError(int errCode); + +/* Signal an warning (does not stop the recorder). */ +void prvTraceWarning(int errCode); + +/******************************************************************************/ +/*** ERROR AND WARNING CODES (check using xTraceGetLastError) *****************/ +/******************************************************************************/ + +#define PSF_ERROR_NONE 0 +#define PSF_ERROR_EVENT_CODE_TOO_LARGE 1 +#define PSF_ERROR_ISR_NESTING_OVERFLOW 2 +#define PSF_ERROR_DWT_NOT_SUPPORTED 3 +#define PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED 4 +#define PSF_ERROR_TZCTRLTASK_NOT_CREATED 5 + +#define PSF_WARNING_SYMBOL_TABLE_SLOTS 101 +#define PSF_WARNING_SYMBOL_MAX_LENGTH 102 +#define PSF_WARNING_OBJECT_DATA_SLOTS 103 +#define PSF_WARNING_STRING_TOO_LONG 104 +#define PSF_WARNING_STREAM_PORT_READ 105 +#define PSF_WARNING_STREAM_PORT_WRITE 106 + +/******************************************************************************/ +/*** INTERNAL STREAMING FUNCTIONS *********************************************/ +/******************************************************************************/ + +/* Saves a symbol name (task name etc.) in symbol table */ +void prvTraceSaveSymbol(const void *address, const char *name); + +/* Deletes a symbol name (task name etc.) from symbol table */ +void prvTraceDeleteSymbol(void *address); + +/* Saves an object data entry (task base priority) in object data table */ +void prvTraceSaveObjectData(const void *address, uint32_t data); + +/* Removes an object data entry (task base priority) from object data table */ +void prvTraceDeleteObjectData(void *address); + +/* Store an event with zero parameters (event ID only) */ +void prvTraceStoreEvent0(uint16_t eventID); + +/* Store an event with one 32-bit parameter (pointer address or an int) */ +void prvTraceStoreEvent1(uint16_t eventID, + uint32_t param1); + +/* Store an event with two 32-bit parameters */ +void prvTraceStoreEvent2(uint16_t eventID, + uint32_t param1, + uint32_t param2); + +/* Store an event with three 32-bit parameters */ +void prvTraceStoreEvent3(uint16_t eventID, + uint32_t param1, + uint32_t param2, + uint32_t param3); + +/* Stores an event with 32-bit integer parameters */ +void prvTraceStoreEvent(int nParam, uint16_t EventID, ...); + +/* Stories an event with a string and 32-bit integer parameters */ +void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...); + +/* Initializes the paged event buffer used by certain stream ports */ +void prvPagedEventBufferInit(char* buffer); + +/* Retrieve a pointer to the paged event buffer */ +void* prvPagedEventBufferGetWritePointer(int sizeOfEvent); + +/* Transfer a full buffer page */ +uint32_t prvPagedEventBufferTransfer(void); + +/* The data structure for commands (a bit overkill) */ +typedef struct +{ + unsigned char cmdCode; + unsigned char param1; + unsigned char param2; + unsigned char param3; + unsigned char param4; + unsigned char param5; + unsigned char checksumLSB; + unsigned char checksumMSB; +} TracealyzerCommandType; + +/* Checks if the provided command is a valid command */ +int prvIsValidCommand(TracealyzerCommandType* cmd); + +/* Executed the received command (Start or Stop) */ +void prvProcessCommand(TracealyzerCommandType* cmd); + +#define vTraceSetStopHook(x) + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + +#else /* when TRC_USE_TRACEALYZER_RECORDER == 0 */ + +#define vTraceEnable(x) +#define xTraceRegisterString(x) 0; (void)x; +#define vTracePrint(chn, ...) (void)chn +#define vTracePrintF(chn, ...) (void)chn +#define vTraceInstanceFinishedNow() +#define vTraceInstanceFinishedNext() +#define vTraceStoreISRBegin(x) (void)x +#define vTraceStoreISREnd(x) (void)x +#define xTraceSetISRProperties(a, b) 0 +#define vTraceStoreKernelObjectName(a, b) +#define xTraceRegisterChannelFormat(eventLabel, formatStr) 0 +#define vTraceChannelPrint(label) +#define vTraceUBData(label, ...) + +#define vTraceSetFilterGroup(x) +#define vTraceSetFilterMask(x) + +#define prvTraceSetReadyEventsEnabled(status) + +#define vTraceExcludeTask(handle) + +#define uiTraceStart() (1) +#define vTraceStart() +#define vTraceStop() + +#ifndef vTraceSetRecorderDataBuffer +#define vTraceSetRecorderDataBuffer(pRecorderData) +#endif + +#ifndef TRC_ALLOC_CUSTOM_BUFFER +#define TRC_ALLOC_CUSTOM_BUFFER(bufname) +#endif + +#define xTraceIsRecordingEnabled() (0) + +#define vTraceSetStopHook(x) + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_RECORDER_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotConfig.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotConfig.h new file mode 100644 index 0000000..1e84934 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotConfig.h @@ -0,0 +1,378 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcSnapshotConfig.h + * + * Configuration parameters for trace recorder library in snapshot mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_SNAPSHOT_CONFIG_H +#define TRC_SNAPSHOT_CONFIG_H + +#define TRC_SNAPSHOT_MODE_RING_BUFFER (0x01) +#define TRC_SNAPSHOT_MODE_STOP_WHEN_FULL (0x02) + +/****************************************************************************** + * TRC_CFG_SNAPSHOT_MODE + * + * Macro which should be defined as one of: + * - TRC_SNAPSHOT_MODE_RING_BUFFER + * - TRC_SNAPSHOT_MODE_STOP_WHEN_FULL + * Default is TRC_SNAPSHOT_MODE_RING_BUFFER. + * + * With TRC_CFG_SNAPSHOT_MODE set to TRC_SNAPSHOT_MODE_RING_BUFFER, the + * events are stored in a ring buffer, i.e., where the oldest events are + * overwritten when the buffer becomes full. This allows you to get the last + * events leading up to an interesting state, e.g., an error, without having + * to store the whole run since startup. + * + * When TRC_CFG_SNAPSHOT_MODE is TRC_SNAPSHOT_MODE_STOP_WHEN_FULL, the + * recording is stopped when the buffer becomes full. This is useful for + * recording events following a specific state, e.g., the startup sequence. + *****************************************************************************/ +#define TRC_CFG_SNAPSHOT_MODE TRC_SNAPSHOT_MODE_RING_BUFFER + +/******************************************************************************* + * TRC_CFG_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the event buffer, i.e., the number of records + * it may store. Most events use one record (4 byte), although some events + * require multiple 4-byte records. You should adjust this to the amount of RAM + * available in the target system. + * + * Default value is 1000, which means that 4000 bytes is allocated for the + * event buffer. + ******************************************************************************/ +#define TRC_CFG_EVENT_BUFFER_SIZE 500 + +/******************************************************************************* + * TRC_CFG_NTASK, TRC_CFG_NISR, TRC_CFG_NQUEUE, TRC_CFG_NSEMAPHORE... + * + * A group of macros which should be defined as integer values, zero or larger. + * + * These define the capacity of the Object Property Table, i.e., the maximum + * number of objects active at any given point, within each object class (e.g., + * task, queue, semaphore, ...). + * + * If tasks or other objects are deleted in your system, this + * setting does not limit the total amount of objects created, only the number + * of objects that have been successfully created but not yet deleted. + * + * Using too small values will cause vTraceError to be called, which stores an + * error message in the trace that is shown when opening the trace file. The + * error message can also be retrieved using xTraceGetLastError. + * + * It can be wise to start with large values for these constants, + * unless you are very confident on these numbers. Then do a recording and + * check the actual usage by selecting View menu -> Trace Details -> + * Resource Usage -> Object Table. + ******************************************************************************/ +#define TRC_CFG_NTASK 10 +#define TRC_CFG_NISR 4 +#define TRC_CFG_NQUEUE 3 +#define TRC_CFG_NSEMAPHORE 4 +#define TRC_CFG_NMUTEX 4 +#define TRC_CFG_NTIMER 2 +#define TRC_CFG_NEVENTGROUP 2 +#define TRC_CFG_NSTREAMBUFFER 3 +#define TRC_CFG_NMESSAGEBUFFER 3 + +/****************************************************************************** + * TRC_CFG_INCLUDE_FLOAT_SUPPORT + * + * Macro which should be defined as either zero (0) or one (1). + * + * If this is zero (0), the support for logging floating point values in + * vTracePrintF is stripped out, in case floating point values are not used or + * supported by the platform used. + * + * Floating point values are only used in vTracePrintF and its subroutines, to + * allow for storing float (%f) or double (%lf) arguments. + * + * vTracePrintF can be used with integer and string arguments in either case. + * + * Default value is 0. + *****************************************************************************/ +#define TRC_CFG_INCLUDE_FLOAT_SUPPORT 0 + +/******************************************************************************* + * TRC_CFG_SYMBOL_TABLE_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the symbol table, in bytes. This symbol table + * stores User Events labels and names of deleted tasks, queues, or other kernel + * objects. If you don't use User Events or delete any kernel + * objects you set this to a very low value. The minimum recommended value is 4. + * A size of zero (0) is not allowed since a zero-sized array may result in a + * 32-bit pointer, i.e., using 4 bytes rather than 0. + * + * Default value is 800. + ******************************************************************************/ +#define TRC_CFG_SYMBOL_TABLE_SIZE 50 + +#if (TRC_CFG_SYMBOL_TABLE_SIZE == 0) +#error "TRC_CFG_SYMBOL_TABLE_SIZE may not be zero!" +#endif + +/****************************************************************************** + * TRC_CFG_NAME_LEN_TASK, TRC_CFG_NAME_LEN_QUEUE, ... + * + * Macros that specify the maximum lengths (number of characters) for names of + * kernel objects, such as tasks and queues. If longer names are used, they will + * be truncated when stored in the recorder. + *****************************************************************************/ +#define TRC_CFG_NAME_LEN_TASK configMAX_TASK_NAME_LEN +#define TRC_CFG_NAME_LEN_ISR 10 +#define TRC_CFG_NAME_LEN_QUEUE 15 +#define TRC_CFG_NAME_LEN_SEMAPHORE 15 +#define TRC_CFG_NAME_LEN_MUTEX 15 +#define TRC_CFG_NAME_LEN_TIMER 15 +#define TRC_CFG_NAME_LEN_EVENTGROUP 15 +#define TRC_CFG_NAME_LEN_STREAMBUFFER 15 +#define TRC_CFG_NAME_LEN_MESSAGEBUFFER 15 + +/****************************************************************************** + *** ADVANCED SETTINGS ******************************************************** + ****************************************************************************** + * The remaining settings are not necessary to modify but allows for optimizing + * the recorder setup for your specific needs, e.g., to exclude events that you + * are not interested in, in order to get longer traces. + *****************************************************************************/ + +/****************************************************************************** +* TRC_CFG_HEAP_SIZE_BELOW_16M +* +* An integer constant that can be used to reduce the buffer usage of memory +* allocation events (malloc/free). This value should be 1 if the heap size is +* below 16 MB (2^24 byte), and you can live with reported addresses showing the +* lower 24 bits only. If 0, you get the full 32-bit addresses. +* +* Default value is 0. +******************************************************************************/ +#define TRC_CFG_HEAP_SIZE_BELOW_16M 0 + +/****************************************************************************** + * TRC_CFG_USE_IMPLICIT_IFE_RULES + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * Tracealyzer groups the events into "instances" based on Instance Finish + * Events (IFEs), produced either by default rules or calls to the recorder + * functions vTraceInstanceFinishedNow and vTraceInstanceFinishedNext. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is one (1), the default IFE rules is + * used, resulting in a "typical" grouping of events into instances. + * If these rules don't give appropriate instances in your case, you can + * override the default rules using vTraceInstanceFinishedNow/Next for one + * or several tasks. The default IFE rules are then disabled for those tasks. + * + * If TRC_CFG_USE_IMPLICIT_IFE_RULES is zero (0), the implicit IFE rules are + * disabled globally. You must then call vTraceInstanceFinishedNow or + * vTraceInstanceFinishedNext to manually group the events into instances, + * otherwise the tasks will appear a single long instance. + * + * The default IFE rules count the following events as "instance finished": + * - Task delay, delay until + * - Task suspend + * - Blocking on "input" operations, i.e., when the task is waiting for the + * next a message/signal/event. But only if this event is blocking. + * + * For details, see trcSnapshotKernelPort.h and look for references to the + * macro trcKERNEL_HOOKS_SET_TASK_INSTANCE_FINISHED. + *****************************************************************************/ +#define TRC_CFG_USE_IMPLICIT_IFE_RULES 1 + +/****************************************************************************** + * TRC_CFG_USE_16BIT_OBJECT_HANDLES + * + * Macro which should be defined as either zero (0) or one (1). + * + * If set to 0 (zero), the recorder uses 8-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrently active objects to 255 of each type (tasks, queues, mutexes, + * etc.) Note: 255, not 256, since handle 0 is reserved. + * + * If set to 1 (one), the recorder uses 16-bit handles to identify kernel + * objects such as tasks and queues. This limits the supported number of + * concurrent objects to 65535 of each type (object class). However, since the + * object property table is limited to 64 KB, the practical limit is about + * 3000 objects in total. + * + * Default is 0 (8-bit handles) + * + * NOTE: An object with handle above 255 will use an extra 4-byte record in + * the event buffer whenever the object is referenced. Moreover, some internal + * tables in the recorder gets slightly larger when using 16-bit handles. + *****************************************************************************/ +#define TRC_CFG_USE_16BIT_OBJECT_HANDLES 0 + +/****************************************************************************** + * TRC_CFG_USE_TRACE_ASSERT + * + * Macro which should be defined as either zero (0) or one (1). + * Default is 1. + * + * If this is one (1), the TRACE_ASSERT macro (used at various locations in the + * trace recorder) will verify that a relevant condition is true. + * If the condition is false, prvTraceError() will be called, which stops the + * recording and stores an error message that is displayed when opening the + * trace in Tracealyzer. + * + * This is used on several places in the recorder code for sanity checks on + * parameters. Can be switched off to reduce the footprint of the tracing, but + * we recommend to have it enabled initially. + *****************************************************************************/ +#define TRC_CFG_USE_TRACE_ASSERT 1 + +/******************************************************************************* + * TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + * + * Macro which should be defined as an integer value. + * + * Set TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER to 1 to enable the + * separate user event buffer (UB). + * In this mode, user events are stored separately from other events, + * e.g., RTOS events. Thereby you can get a much longer history of + * user events as they don't need to share the buffer space with more + * frequent events. + * + * The UB is typically used with the snapshot ring-buffer mode, so the + * recording can continue when the main buffer gets full. And since the + * main buffer then overwrites the earliest events, Tracealyzer displays + * "Unknown Actor" instead of task scheduling for periods with UB data only. + * + * In UB mode, user events are structured as UB channels, which contains + * a channel name and a default format string. Register a UB channel using + * xTraceRegisterUBChannel. + * + * Events and data arguments are written using vTraceUBEvent and + * vTraceUBData. They are designed to provide efficient logging of + * repeating events, using the same format string within each channel. + * + * Examples: + * + * traceString chn1 = xTraceRegisterString("Channel 1"); + * traceString fmt1 = xTraceRegisterString("Event!"); + * traceUBChannel UBCh1 = xTraceRegisterUBChannel(chn1, fmt1); + * + * traceString chn2 = xTraceRegisterString("Channel 2"); + * traceString fmt2 = xTraceRegisterString("X: %d, Y: %d"); + * traceUBChannel UBCh2 = xTraceRegisterUBChannel(chn2, fmt2); + * + * // Result in "[Channel 1] Event!" + * vTraceUBEvent(UBCh1); + * + * // Result in "[Channel 2] X: 23, Y: 19" + * vTraceUBData(UBCh2, 23, 19); + * + * You can also use the other user event functions, like vTracePrintF. + * as they are then rerouted to the UB instead of the main event buffer. + * vTracePrintF then looks up the correct UB channel based on the + * provided channel name and format string, or creates a new UB channel + * if no match is found. The format string should therefore not contain + * "random" messages but mainly format specifiers. Random strings should + * be stored using %s and with the string as an argument. + * + * // Creates a new UB channel ("Channel 2", "%Z: %d") + * vTracePrintF(chn2, "%Z: %d", value1); + * + * // Finds the existing UB channel + * vTracePrintF(chn2, "%Z: %d", value2); + + ******************************************************************************/ +#define TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER 0 + +/******************************************************************************* + * TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE + * + * Macro which should be defined as an integer value. + * + * This defines the capacity of the user event buffer (UB), in number of slots. + * A single user event can use multiple slots, depending on the arguments. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE 200 + +/******************************************************************************* + * TRC_CFG_UB_CHANNELS + * + * Macro which should be defined as an integer value. + * + * This defines the number of User Event Buffer Channels (UB channels). + * These are used to structure the events when using the separate user + * event buffer, and contains both a User Event Channel (the name) and + * a default format string for the channel. + * + * Only applicable if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is 1. + ******************************************************************************/ +#define TRC_CFG_UB_CHANNELS 32 + +/******************************************************************************* + * TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * + * Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + ******************************************************************************/ +#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +#endif /*TRC_SNAPSHOT_CONFIG_H*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotRecorder.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotRecorder.c new file mode 100644 index 0000000..9f2d113 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcSnapshotRecorder.c @@ -0,0 +1,3103 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcSnapshotRecorder.c + * + * The generic core of the trace recorder's snapshot mode. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#include "trcRecorder.h" + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT) + +#if (TRC_USE_TRACEALYZER_RECORDER == 1) + +#include +#include + #ifndef __HIWARE__ /* << EST */ +#include +#endif + +#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)) + #error "CUSTOM timestamping mode is not (yet) supported in snapshot mode!" +#endif + +/* DO NOT CHANGE */ +#define TRACE_MINOR_VERSION 5 +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) +static traceHandle isrstack[TRC_CFG_MAX_ISR_NESTING]; +int32_t isPendingContextSwitch = 0; +#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1) */ + +#if !defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1 +static int readyEventsEnabled = 1; +#endif /*!defined TRC_CFG_INCLUDE_READY_EVENTS || TRC_CFG_INCLUDE_READY_EVENTS == 1*/ + +/******************************************************************************* + * uiTraceTickCount + * + * This variable is should be updated by the Kernel tick interrupt. This does + * not need to be modified when developing a new timer port. It is preferred to + * keep any timer port changes in the HWTC macro definitions, which typically + * give sufficient flexibility. + ******************************************************************************/ +uint32_t uiTraceTickCount = 0; + +uint32_t trace_disable_timestamp = 0; + +static uint32_t last_timestamp = 0; + +/* Flag that shows if inside a critical section of the recorder */ +volatile int recorder_busy = 0; + +/* Holds the value set by vTraceSetFrequency */ +uint32_t timestampFrequency = 0; + +/* The last error message of the recorder. NULL if no error message. */ +const char* traceErrorMessage = NULL; + +int8_t nISRactive = 0; + +traceHandle handle_of_last_logged_task = 0; + +/* Called when the recorder is stopped, set by vTraceSetStopHook. */ +TRACE_STOP_HOOK vTraceStopHookPtr = (TRACE_STOP_HOOK)0; + +uint16_t CurrentFilterMask = 0xFFFF; + +uint16_t CurrentFilterGroup = FilterGroup0; + +extern int8_t nISRactive; + +extern traceHandle handle_of_last_logged_task; + +/*************** Private Functions *******************************************/ +static void prvStrncpy(char* dst, const char* src, uint32_t maxLength); +static uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id); +static void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength); +static void* prvTraceNextFreeEventBufferSlot(void); +static uint16_t prvTraceGetDTS(uint16_t param_maxDTS); +static traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel); +static void prvTraceUpdateCounters(void); + +void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size); + +#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) +static void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nEntries); +#endif + +static traceString prvTraceCreateSymbolTableEntry(const char* name, + uint8_t crc6, + uint8_t len, + traceString channel); + +static traceString prvTraceLookupSymbolTableEntry(const char* name, + uint8_t crc6, + uint8_t len, + traceString channel); + + +#if (TRC_CFG_INCLUDE_ISR_TRACING == 0) +/* ISR tracing is turned off */ +void prvTraceIncreaseISRActive(void); +void prvTraceDecreaseISRActive(void); +#endif /*(TRC_CFG_INCLUDE_ISR_TRACING == 0)*/ + +#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) +static uint8_t prvTraceGet8BitHandle(traceHandle handle); +#else +#define prvTraceGet8BitHandle(x) ((uint8_t)x) +#endif + + +#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) && (TRC_CFG_SCHEDULING_ONLY == 0) +static uint32_t heapMemUsage = 0; +#endif + +#if (TRC_CFG_SCHEDULING_ONLY == 0) +static uint32_t prvTraceGetParam(uint32_t, uint32_t); +#endif + +/******************************************************************************* + * prvTraceInitTraceData + * + * Allocates and initializes the recorder data structure, based on the constants + * in trcConfig.h. This allows for allocating the data on the heap, instead of + * using a static declaration. + ******************************************************************************/ +static void prvTraceInitTraceData(void); + +/******************************************************************************* + * prvTracePortGetTimeStamp + * + * Returns the current time based on the HWTC macros which provide a hardware + * isolation layer towards the hardware timer/counter. + * + * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue + * or the trace recorder library. Typically you should not need to change + * the code of prvTracePortGetTimeStamp if using the HWTC macros. + * + ******************************************************************************/ +void prvTracePortGetTimeStamp(uint32_t *puiTimestamp); + +static void prvTraceTaskInstanceFinish(int8_t direct); + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +static void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list vl); + +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) +static void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl); +static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl); +static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots); +#endif /*(TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)*/ +#endif /* ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) */ + +/********* Public Functions **************************************************/ + +uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass); + +/******************************************************************************* + * prvTraceError + * + * Called by various parts in the recorder. Stops the recorder and stores a + * pointer to an error message, which is printed by the monitor task. + ******************************************************************************/ +void prvTraceError(const char* msg); + +/****************************************************************************** +* vTraceEnable(int startOption) - snapshot mode +* +* Initializes and optionally starts the trace, depending on the start option. +* To use the trace recorder, the startup must call vTraceEnable before any RTOS +* calls are made (including "create" calls). Three start options are provided: +* +* TRC_START: Starts the tracing directly. In snapshot mode this allows for +* starting the trace at any point in your code, assuming vTraceEnable(TRC_INIT) +* has been called in the startup. +* Can also be used for streaming without Tracealyzer control, e.g. to a local +* flash file system (assuming such a "stream port", see trcStreamingPort.h). +* +* TRC_INIT: Initializes the trace recorder, but does not start the tracing. +* In snapshot mode, this must be followed by a vTraceEnable(TRC_START) sometime +* later. +* +* Usage examples, in snapshot mode: +* +* Snapshot trace, from startup: +* +* vTraceEnable(TRC_START); +* +* +* Snapshot trace, from a later point: +* +* vTraceEnable(TRC_INIT); +* +* ... +* vTraceEnable(TRC_START); // e.g., in task context, at some relevant event +* +* +* Note: See other implementation of vTraceEnable in trcStreamingRecorder.c +******************************************************************************/ +void vTraceEnable(int startOption) +{ + prvTraceInitTraceData(); + + if (startOption == TRC_START) + { + vTraceStart(); + } + else if (startOption == TRC_START_AWAIT_HOST) + { + prvTraceError("vTraceEnable(TRC_START_AWAIT_HOST) not allowed in Snapshot mode"); + } + else if (startOption != TRC_INIT) + { + prvTraceError("Unexpected argument to vTraceEnable (snapshot mode)"); + } +} + +/******************************************************************************* + * vTraceSetRecorderDataBuffer + * + * If custom allocation is used, this function must be called so the recorder + * library knows where to save the trace data. + ******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) +void vTraceSetRecorderDataBuffer(void* pRecorderData) +{ + TRACE_ASSERT(pRecorderData != NULL, "vTraceSetRecorderDataBuffer, pRecorderData == NULL", TRC_UNUSED); + RecorderDataPtr = pRecorderData; +} +#endif + +/******************************************************************************* + * vTraceSetStopHook + * + * Sets a function to be called when the recorder is stopped. This can be used + * to save the trace to a file system, if available. This is only implemented + * for snapshot mode. + ******************************************************************************/ +void vTraceSetStopHook(TRACE_STOP_HOOK stopHookFunction) +{ + vTraceStopHookPtr = stopHookFunction; +} + +/******************************************************************************* + * vTraceClear + * + * Resets the recorder. Only necessary if a restart is desired - this is not + * needed in the startup initialization. + ******************************************************************************/ +void vTraceClear(void) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + trcCRITICAL_SECTION_BEGIN(); + RecorderDataPtr->absTimeLastEventSecond = 0; + RecorderDataPtr->absTimeLastEvent = 0; + RecorderDataPtr->nextFreeIndex = 0; + RecorderDataPtr->numEvents = 0; + RecorderDataPtr->bufferIsFull = 0; + traceErrorMessage = NULL; + RecorderDataPtr->internalErrorOccured = 0; + (void)memset(RecorderDataPtr->eventData, 0, RecorderDataPtr->maxEvents * 4); + handle_of_last_logged_task = 0; + trcCRITICAL_SECTION_END(); +} + +/******************************************************************************* + * uiTraceStart + * + * Starts the recorder. The recorder will not be started if an error has been + * indicated using prvTraceError, e.g. if any of the Nx constants in trcConfig.h + * has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc). + * + * Returns 1 if the recorder was started successfully. + * Returns 0 if the recorder start was prevented due to a previous internal + * error. In that case, check xTraceGetLastError to get the error message. + * Any error message is also presented when opening a trace file. + * + * This function is obsolete, but has been saved for backwards compatibility. + * We recommend using vTraceEnable instead. + ******************************************************************************/ +uint32_t uiTraceStart(void) +{ + traceHandle handle; + TRACE_ALLOC_CRITICAL_SECTION(); + + handle = 0; + + if (RecorderDataPtr == NULL) + { + prvTraceError("RecorderDataPtr is NULL. Call vTraceInitTraceData() before starting trace."); + return 0; + } + + if (RecorderDataPtr->recorderActive == 1) + return 1; /* Already running */ + + if (traceErrorMessage == NULL) + { + trcCRITICAL_SECTION_BEGIN(); + RecorderDataPtr->recorderActive = 1; + + handle = TRACE_GET_TASK_NUMBER(TRACE_GET_CURRENT_TASK()); + if (handle == 0) + { + /* This occurs if the scheduler is not yet started. + This creates a dummy "(startup)" task entry internally in the + recorder */ + handle = prvTraceGetObjectHandle(TRACE_CLASS_TASK); + prvTraceSetObjectName(TRACE_CLASS_TASK, handle, "(startup)"); + + prvTraceSetPriorityProperty(TRACE_CLASS_TASK, handle, 0); + } + + prvTraceStoreTaskswitch(handle); /* Register the currently running task */ + trcCRITICAL_SECTION_END(); + } + return RecorderDataPtr->recorderActive; +} + +/******************************************************************************* + * vTraceStart + * + * Starts the recorder. The recorder will not be started if an error has been + * indicated using prvTraceError, e.g. if any of the Nx constants in trcConfig.h + * has a too small value (TRC_CFG_NTASK, TRC_CFG_NQUEUE, etc). + * + * This function is obsolete, but has been saved for backwards compatibility. + * We recommend using vTraceEnable instead. + ******************************************************************************/ +void vTraceStart(void) +{ + (void)uiTraceStart(); +} + +/******************************************************************************* + * vTraceStop + * + * Stops the recorder. The recording can be resumed by calling vTraceStart. + * This does not reset the recorder. Use vTraceClear if that is desired. + ******************************************************************************/ +void vTraceStop(void) +{ + if (RecorderDataPtr != NULL) + { + RecorderDataPtr->recorderActive = 0; + } + + if (vTraceStopHookPtr != (TRACE_STOP_HOOK)0) + { + (*vTraceStopHookPtr)(); /* An application call-back function. */ + } +} + +/******************************************************************************* +* xTraceIsRecordingEnabled +* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0. +******************************************************************************/ +int xTraceIsRecordingEnabled(void) +{ + if (RecorderDataPtr != NULL) + { + return (int)RecorderDataPtr->recorderActive; + } + else + { + return 0; + } +} + +/******************************************************************************* + * xTraceGetLastError + * + * Gives the last error message, if any. NULL if no error message is stored. + * Any error message is also presented when opening a trace file. + ******************************************************************************/ +const char* xTraceGetLastError(void) +{ + return traceErrorMessage; +} + +/******************************************************************************* +* vTraceClearError +* +* Removes any previous error message generated by recorder calling prvTraceError. +* By calling this function, it may be possible to start/restart the trace +* despite errors in the recorder, but there is no guarantee that the trace +* recorder will work correctly in that case, depending on the type of error. +******************************************************************************/ +void vTraceClearError(void) +{ + traceErrorMessage = NULL; + if (RecorderDataPtr != NULL) + { + RecorderDataPtr->internalErrorOccured = 0; + } +} + +/******************************************************************************* + * xTraceGetTraceBuffer + * + * Returns a pointer to the recorder data structure. Use this together with + * uiTraceGetTraceBufferSize if you wish to implement an own store/upload + * solution, e.g., in case a debugger connection is not available for uploading + * the data. + ******************************************************************************/ +void* xTraceGetTraceBuffer(void) +{ + return RecorderDataPtr; +} + +/******************************************************************************* + * uiTraceGetTraceBufferSize + * + * Gets the size of the recorder data structure. For use together with + * vTraceGetTraceBuffer if you wish to implement an own store/upload solution, + * e.g., in case a debugger connection is not available for uploading the data. + ******************************************************************************/ +uint32_t uiTraceGetTraceBufferSize(void) +{ + return sizeof(RecorderDataType); +} + +/****************************************************************************** + * prvTraceTaskInstanceFinish + * + * Private common function for the vTraceTaskInstanceFinishXXX functions. + *****************************************************************************/ +static void prvTraceTaskInstanceFinish(int8_t direct) +{ + TaskInstanceStatusEvent* tis; + uint8_t dts45; + + TRACE_ALLOC_CRITICAL_SECTION(); + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + dts45 = (uint8_t)prvTraceGetDTS(0xFF); + tis = (TaskInstanceStatusEvent*) prvTraceNextFreeEventBufferSlot(); + if (tis != NULL) + { + if (direct == 0) + tis->type = TASK_INSTANCE_FINISHED_NEXT_KSE; + else + tis->type = TASK_INSTANCE_FINISHED_DIRECT; + + tis->dts = dts45; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} + +/****************************************************************************** + * vTraceInstanceFinishedNext(void) + * + * Marks the current task instance as finished on the next kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + * + * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h + * + * Example: + * + * while(1) + * { + * xQueueReceive(CommandQueue, &command, timeoutDuration); + * processCommand(command); + * vTraceInstanceFinishedNext(); + * } + *****************************************************************************/ +void vTraceInstanceFinishedNext(void) +{ + prvTraceTaskInstanceFinish(0); +} + +/****************************************************************************** + * vTraceInstanceFinishedNow(void) + * + * Marks the current task instance as finished at this very instant. + * This makes the viewer to splits the current fragment at this point and begin + * a new actor instance. + * + * See also TRC_CFG_USE_IMPLICIT_IFE_RULES in trcConfig.h + * + * Example: + * + * This example will generate two instances for each loop iteration. + * The first instance ends at vTraceInstanceFinishedNow(), while the second + * instance ends at the next xQueueReceive call. + * + * while (1) + * { + * xQueueReceive(CommandQueue, &command, timeoutDuration); + * ProcessCommand(command); + * vTraceInstanceFinishedNow(); + * DoSometingElse(); + * vTraceInstanceFinishedNext(); + * } + *****************************************************************************/ +void vTraceInstanceFinishedNow(void) +{ + prvTraceTaskInstanceFinish(1); +} + +/******************************************************************************* + * Interrupt recording functions + ******************************************************************************/ + +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) + +/******************************************************************************* + * xTraceSetISRProperties + * + * Stores a name and priority level for an Interrupt Service Routine, to allow + * for better visualization. Returns a traceHandle used by vTraceStoreISRBegin. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ + traceHandle xTraceSetISRProperties(const char* name, uint8_t priority) +{ + static traceHandle handle = 0; + handle++; + TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "xTraceSetISRProperties: Invalid value for handle", 0); + TRACE_ASSERT(name != NULL, "xTraceSetISRProperties: name == NULL", 0); + + prvTraceSetObjectName(TRACE_CLASS_ISR, handle, name); + prvTraceSetPriorityProperty(TRACE_CLASS_ISR, handle, priority); + + return handle; +} + +/******************************************************************************* + * vTraceStoreISRBegin + * + * Registers the beginning of an Interrupt Service Routine, using a traceHandle + * provided by xTraceSetISRProperties. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ +void vTraceStoreISRBegin(traceHandle handle) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("vTraceStoreISRBegin - recorder busy! See code comment."); + return; + } + trcCRITICAL_SECTION_BEGIN(); + + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + uint16_t dts4; + + TRACE_ASSERT(handle != 0, "vTraceStoreISRBegin: Invalid ISR handle (NULL)", TRC_UNUSED); + TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_ISR], "vTraceStoreISRBegin: Invalid ISR handle (> NISR)", TRC_UNUSED); + + dts4 = (uint16_t)prvTraceGetDTS(0xFFFF); + + if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */ + { + if (nISRactive < TRC_CFG_MAX_ISR_NESTING) + { + TSEvent* ts; + uint8_t hnd8 = prvTraceGet8BitHandle(handle); + isrstack[nISRactive] = handle; + nISRactive++; + ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); + if (ts != NULL) + { + ts->type = TS_ISR_BEGIN; + ts->dts = dts4; + ts->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + else + { + /* This should not occur unless something is very wrong */ + prvTraceError("Too many nested interrupts!"); + } + } + } + trcCRITICAL_SECTION_END(); +} + +/******************************************************************************* + * vTraceStoreISREnd + * + * Registers the end of an Interrupt Service Routine. + * + * The parameter pendingISR indicates if the interrupt has requested a + * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the + * interrupt is assumed to return to the previous context. + * + * Example: + * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt + * traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder + * ... + * traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(traceHandleIsrTimer1); + * ... + * vTraceStoreISREnd(0); + * } + ******************************************************************************/ +void vTraceStoreISREnd(int pendingISR) +{ + TSEvent* ts; + uint16_t dts5; + uint8_t hnd8 = 0, type = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if (! RecorderDataPtr->recorderActive || ! handle_of_last_logged_task) + { + return; + } + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("vTraceStoreISREnd - recorder busy! See code comment."); + return; + } + + if (nISRactive == 0) + { + prvTraceError("Unmatched call to vTraceStoreISREnd (nISRactive == 0, expected > 0)"); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + isPendingContextSwitch |= pendingISR; /* Is there a pending context switch right now? */ + nISRactive--; + if (nISRactive > 0) + { + /* Return to another ISR */ + type = TS_ISR_RESUME; + hnd8 = prvTraceGet8BitHandle(isrstack[nISRactive - 1]); /* isrstack[nISRactive] is the handle of the ISR we're currently exiting. isrstack[nISRactive - 1] is the handle of the ISR that was executing previously. */ + } + else if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended())) + { + /* Return to interrupted task, if no context switch will occur in between. */ + type = TS_TASK_RESUME; + hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task); + } + + if (type != 0) + { + dts5 = (uint16_t)prvTraceGetDTS(0xFFFF); + ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); + if (ts != NULL) + { + ts->type = type; + ts->objHandle = hnd8; + ts->dts = dts5; + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END(); +} + +#else + +/* ISR tracing is turned off */ +void prvTraceIncreaseISRActive(void) +{ + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + nISRactive++; +} + +void prvTraceDecreaseISRActive(void) +{ + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + nISRactive--; +} +#endif /* (TRC_CFG_INCLUDE_ISR_TRACING == 1)*/ + + +/********************************************************************************/ +/* User Event functions */ +/********************************************************************************/ + +#define MAX_ARG_SIZE (4+32) + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +static uint8_t writeInt8(void * buffer, uint8_t i, uint8_t value) +{ + TRACE_ASSERT(buffer != NULL, "writeInt8: buffer == NULL", 0); + + if (i >= MAX_ARG_SIZE) + { + return 255; + } + + ((uint8_t*)buffer)[i] = value; + + if (i + 1 > MAX_ARG_SIZE) + { + return 255; + } + + return ((uint8_t) (i + 1)); +} +#endif + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +static uint8_t writeInt16(void * buffer, uint8_t i, uint16_t value) +{ + TRACE_ASSERT(buffer != NULL, "writeInt16: buffer == NULL", 0); + + /* Align to multiple of 2 */ + while ((i % 2) != 0) + { + if (i >= MAX_ARG_SIZE) + { + return 255; + } + + ((uint8_t*)buffer)[i] = 0; + i++; + } + + if (i + 2 > MAX_ARG_SIZE) + { + return 255; + } + + ((uint16_t*)buffer)[i/2] = value; + + return ((uint8_t) (i + 2)); +} +#endif + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +static uint8_t writeInt32(void * buffer, uint8_t i, uint32_t value) +{ + TRACE_ASSERT(buffer != NULL, "writeInt32: buffer == NULL", 0); + + /* A 32 bit value should begin at an even 4-byte address */ + while ((i % 4) != 0) + { + if (i >= MAX_ARG_SIZE) + { + return 255; + } + + ((uint8_t*)buffer)[i] = 0; + i++; + } + + if (i + 4 > MAX_ARG_SIZE) + { + return 255; + } + + ((uint32_t*)buffer)[i/4] = value; + + return ((uint8_t) (i + 4)); +} +#endif + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT)) +static uint8_t writeFloat(void * buffer, uint8_t i, float value) +{ + TRACE_ASSERT(buffer != NULL, "writeFloat: buffer == NULL", 0); + + /* A 32 bit value should begin at an even 4-byte address */ + while ((i % 4) != 0) + { + if (i >= MAX_ARG_SIZE) + { + return 255; + } + + ((uint8_t*)buffer)[i] = 0; + i++; + } + + if (i + 4 > MAX_ARG_SIZE) + { + return 255; + } + + ((float*)buffer)[i/4] = value; + + return i + 4; +} +#endif + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_INCLUDE_FLOAT_SUPPORT)) +static uint8_t writeDouble(void * buffer, uint8_t i, double value) +{ + uint32_t * dest; + uint32_t * src = (uint32_t*)&value; + + TRACE_ASSERT(buffer != NULL, "writeDouble: buffer == NULL", 0); + + /* The double is written as two 32 bit values, and should begin at an even + 4-byte address (to avoid having to align with 8 byte) */ + while (i % 4 != 0) + { + if (i >= MAX_ARG_SIZE) + { + return 255; + } + + ((uint8_t*)buffer)[i] = 0; + i++; + } + + if (i + 8 > MAX_ARG_SIZE) + { + return 255; + } + + dest = &(((uint32_t *)buffer)[i/4]); + + dest[0] = src[0]; + dest[1] = src[1]; + + return i + 8; +} +#endif + +/******************************************************************************* + * prvTraceUserEventFormat + * + * Parses the format string and stores the arguments in the buffer. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +static uint8_t prvTraceUserEventFormat(const char* formatStr, va_list vl, uint8_t* buffer, uint8_t byteOffset) +{ + uint16_t formatStrIndex = 0; + uint8_t argCounter = 0; + uint8_t i = byteOffset; + + while (formatStr[formatStrIndex] != '\0') + { + if (formatStr[formatStrIndex] == '%') + { + argCounter++; + + if (argCounter > 15) + { + prvTraceError("vTracePrintF - Too many arguments, max 15 allowed!"); + return 0; + } + + formatStrIndex++; + + while ((formatStr[formatStrIndex] >= '0' && formatStr[formatStrIndex] <= '9') || formatStr[formatStrIndex] == '#' || formatStr[formatStrIndex] == '.') + formatStrIndex++; + + if (formatStr[formatStrIndex] != '\0') + { + switch (formatStr[formatStrIndex]) + { + case 'd': i = writeInt32( buffer, + i, + (uint32_t)va_arg(vl, uint32_t)); + break; + case 'x': + case 'X': + case 'u': i = writeInt32( buffer, + i, + (uint32_t)va_arg(vl, uint32_t)); + break; + case 's': i = writeInt16( buffer, + i, + xTraceRegisterString((char*)va_arg(vl, char*))); + break; + +#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT) + /* Yes, "double" as type also in the float + case. This since "float" is promoted into "double" + by the va_arg stuff. */ + case 'f': i = writeFloat( buffer, + i, + (float)va_arg(vl, double)); + break; +#else + /* No support for floats, but attempt to store a float user event + avoid a possible crash due to float reference. Instead store the + data on uint_32 format (will not be displayed anyway). This is just + to keep va_arg and i consistent. */ + + case 'f': i = writeInt32( buffer, + i, + (uint32_t)va_arg(vl, double)); + break; +#endif + case 'l': + formatStrIndex++; + switch (formatStr[formatStrIndex]) + { +#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT) + case 'f': i = writeDouble(buffer, + i, + (double)va_arg(vl, double)); + break; +#else + /* No support for floats, but attempt to store a float user event + avoid a possible crash due to float reference. Instead store the + data on uint_32 format (will not be displayed anyway). This is just + to keep va_arg and i consistent. */ + case 'f': i = writeInt32( buffer, /* In this case, the value will not be shown anyway */ + i, + (uint32_t)va_arg(vl, double)); + + i = writeInt32( buffer, /* Do it twice, to write in total 8 bytes */ + i, + (uint32_t)va_arg(vl, double)); + break; +#endif + + } + break; + case 'h': + formatStrIndex++; + switch (formatStr[formatStrIndex]) + { + case 'd': i = writeInt16( buffer, + i, + (uint16_t)va_arg(vl, uint32_t)); + break; + case 'u': i = writeInt16( buffer, + i, + (uint16_t)va_arg(vl, uint32_t)); + break; + } + break; + case 'b': + formatStrIndex++; + switch (formatStr[formatStrIndex]) + { + case 'd': i = writeInt8( buffer, + i, + (uint8_t)va_arg(vl, uint32_t)); + break; + + case 'u': i = writeInt8( buffer, + i, + (uint8_t)va_arg(vl, uint32_t)); + break; + } + break; + } + } + else + break; + } + formatStrIndex++; + if (i == 255) + { + prvTraceError("vTracePrintF - Too large arguments, max 32 byte allowed!"); + return 0; + } + } + return (uint8_t)(i+3)/4; +} +#endif + +/******************************************************************************* + * prvTraceClearChannelBuffer + * + * Clears a number of items in the channel buffer, starting from nextSlotToWrite. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +static void prvTraceClearChannelBuffer(uint32_t count) +{ + uint32_t slots; + + TRACE_ASSERT(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE >= count, + "prvTraceClearChannelBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); + + /* Check if we're close to the end of the buffer */ + if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + { + slots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ + (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, slots); + (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[0], 0, (count - slots)); + } + else + (void)memset(&RecorderDataPtr->userEventBuffer.channelBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite], 0, count); +} +#endif + +/******************************************************************************* + * prvTraceCopyToDataBuffer + * + * Copies a number of items to the data buffer, starting from nextSlotToWrite. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +static void prvTraceCopyToDataBuffer(uint32_t* data, uint32_t count) +{ + uint32_t slots; + + TRACE_ASSERT(data != NULL, + "prvTraceCopyToDataBuffer: data == NULL.", TRC_UNUSED); + TRACE_ASSERT(count <= TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE, + "prvTraceCopyToDataBuffer: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); + /* Check if we're close to the end of the buffer */ + if (RecorderDataPtr->userEventBuffer.nextSlotToWrite + count > TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE) + { + slots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE - RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Number of slots before end of buffer */ + (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, slots * 4); + (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[0], data + slots, (count - slots) * 4); + } + else + { + (void)memcpy(&RecorderDataPtr->userEventBuffer.dataBuffer[RecorderDataPtr->userEventBuffer.nextSlotToWrite * 4], data, count * 4); + } +} +#endif + +/******************************************************************************* + * prvTraceUBHelper1 + * + * Calls on prvTraceUserEventFormat() to do the actual formatting, then goes on + * to the next helper function. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +static void prvTraceUBHelper1(traceUBChannel channel, traceString eventLabel, traceString formatLabel, va_list vl) +{ + uint32_t data[(3 + MAX_ARG_SIZE) / 4]; + uint8_t byteOffset = 4; /* Need room for timestamp */ + uint8_t noOfSlots; + + if (channel == 0) + { + /* We are dealing with an unknown channel format pair */ + byteOffset = (uint8_t)(byteOffset + 4); /* Also need room for channel and format */ + ((uint16_t*)data)[2] = eventLabel; + ((uint16_t*)data)[3] = formatLabel; + } + + noOfSlots = prvTraceUserEventFormat((char*)&(RecorderDataPtr->SymbolTable.symbytes[formatLabel+4]), vl, (uint8_t*)data, byteOffset); + + prvTraceUBHelper2(channel, data, noOfSlots); +} +#endif + +/******************************************************************************* + * prvTraceUBHelper2 + * + * This function simply copies the data buffer to the actual user event buffer. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +static void prvTraceUBHelper2(traceUBChannel channel, uint32_t* data, uint32_t noOfSlots) +{ + static uint32_t old_timestamp = 0; + uint32_t old_nextSlotToWrite = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE >= noOfSlots, "prvTraceUBHelper2: TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE is too small to handle this event.", TRC_UNUSED); + + trcCRITICAL_SECTION_BEGIN(); + /* Store the timestamp */ + prvTracePortGetTimeStamp(data); + + if (*data < old_timestamp) + { + RecorderDataPtr->userEventBuffer.wraparoundCounter++; + } + + old_timestamp = *data; + + /* Start by erasing any information in the channel buffer */ + prvTraceClearChannelBuffer(noOfSlots); + + prvTraceCopyToDataBuffer(data, noOfSlots); /* Will wrap around the data if necessary */ + + old_nextSlotToWrite = RecorderDataPtr->userEventBuffer.nextSlotToWrite; /* Save the index that we want to write the channel data at when we're done */ + RecorderDataPtr->userEventBuffer.nextSlotToWrite = (RecorderDataPtr->userEventBuffer.nextSlotToWrite + noOfSlots) % TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE; /* Make sure we never end up outside the buffer */ + + /* Write to the channel buffer to indicate that this user event is ready to be used */ + if (channel != 0) + { + RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = channel; + } + else + { + /* 0xFF indicates that this is not a normal channel id */ + RecorderDataPtr->userEventBuffer.channelBuffer[old_nextSlotToWrite] = (traceUBChannel)0xFF; + } + trcCRITICAL_SECTION_END(); +} +#endif + +/******************************************************************************* + * xTraceRegisterUBChannel + * + * Registers a channel for Separated User Events, i.e., those stored in the + * separate user event buffer. + * + * Note: Only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is enabled in + * trcSnapshotConfig.h + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +traceUBChannel xTraceRegisterUBChannel(traceString channel, traceString formatStr) +{ + uint8_t i; + traceUBChannel retVal = 0; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(formatStr != 0, "xTraceRegisterChannelFormat: formatStr == 0", (traceUBChannel)0); + + trcCRITICAL_SECTION_BEGIN(); + for (i = 1; i <= TRC_CFG_UB_CHANNELS; i++) /* Size of the channels buffer is TRC_CFG_UB_CHANNELS + 1. Index 0 is unused. */ + { + if(RecorderDataPtr->userEventBuffer.channels[i].name == 0 && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == 0) + { + /* Found empty slot */ + RecorderDataPtr->userEventBuffer.channels[i].name = channel; + RecorderDataPtr->userEventBuffer.channels[i].defaultFormat = formatStr; + retVal = (traceUBChannel)i; + break; + } + + if (RecorderDataPtr->userEventBuffer.channels[i].name == channel && RecorderDataPtr->userEventBuffer.channels[i].defaultFormat == formatStr) + { + /* Found a match */ + retVal = (traceUBChannel)i; + break; + } + } + trcCRITICAL_SECTION_END(); + + return retVal; +} +#endif + +/****************************************************************************** + * vTraceUBData + * + * Slightly faster version of vTracePrintF() due to no lookups. + * + * Note: This is only available if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER is + * enabled in trcSnapshotConfig.h + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +void vTraceUBData(traceUBChannel channelPair, ...) +{ + va_list vl; + + TRACE_ASSERT(channelPair != 0, "vTraceUBData: Not a valid traceUBChannel!", TRC_UNUSED); + + va_start(vl, channelPair); + vTraceUBData_Helper(channelPair, vl); + va_end(vl); +} +#endif + +/* Extracts the channel name and format string from the traceUBChannel, then calls prvTraceUBHelper1. */ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +void vTraceUBData_Helper(traceUBChannel channelPair, va_list vl) +{ + traceString channel; + traceString formatStr; + + TRACE_ASSERT(channelPair != 0, "vTraceUBData_Helper: channelPair == 0", TRC_UNUSED); + TRACE_ASSERT(channelPair <= TRC_CFG_UB_CHANNELS, "vTraceUBData_Helper: ", TRC_UNUSED); + + channel = RecorderDataPtr->userEventBuffer.channels[channelPair].name; + formatStr = RecorderDataPtr->userEventBuffer.channels[channelPair].defaultFormat; + + prvTraceUBHelper1(channelPair, channel, formatStr, vl); +} +#endif + +/****************************************************************************** + * vTraceUBEvent + * + * Slightly faster version of ... due to no lookups. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) && (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1)) +void vTraceUBEvent(traceUBChannel channelPair) +{ + uint32_t data[(3 + MAX_ARG_SIZE) / 4]; + + TRACE_ASSERT(channelPair != 0, "vTraceUBEvent: channelPair == 0", TRC_UNUSED); + TRACE_ASSERT(channelPair <= TRC_CFG_UB_CHANNELS, "vTraceUBEvent: ", TRC_UNUSED); + + prvTraceUBHelper2(channelPair, data, 1); /* Only need one slot for timestamp */ +} +#endif + +/****************************************************************************** + * vTracePrintF + * + * Generates User Event with formatted text and data, similar to a "printf". + * It is very fast compared to a normal "printf" since this function only + * stores the arguments. The actual formatting is done + * on the host PC when the trace is displayed in the viewer tool. + * + * User Event labels are created using xTraceRegisterString. + * Example: + * + * traceString adc_uechannel = xTraceRegisterString("ADC User Events"); + * ... + * vTracePrintF(adc_uechannel, + * "ADC channel %d: %lf volts", + * ch, (double)adc_reading/(double)scale); + * + * This can be combined into one line, if desired, but this is slower: + * + * vTracePrintF(xTraceRegisterString("ADC User Events"), + * "ADC channel %d: %lf volts", + * ch, (double)adc_reading/(double)scale); + * + * Calling xTraceRegisterString multiple times will not create duplicate entries, but + * it is of course faster to just do it once, and then keep the handle for later + * use. If you don't have any data arguments, only a text label/string, it is + * better to use vTracePrint - it is faster. + * + * Format specifiers supported: + * %d - 32 bit signed integer + * %u - 32 bit unsigned integer + * %f - 32 bit float + * %s - string (is copied to the recorder symbol table) + * %hd - 16 bit signed integer + * %hu - 16 bit unsigned integer + * %bd - 8 bit signed integer + * %bu - 8 bit unsigned integer + * %lf - double-precision float (Note! See below...) + * + * Up to 15 data arguments are allowed, with a total size of maximum 32 byte. + * In case this is exceeded, the user event is changed into an error message. + * + * The data is stored in trace buffer, and is packed to allow storing multiple + * smaller data entries in the same 4-byte record, e.g., four 8-bit values. + * A string requires two bytes, as the symbol table is limited to 64K. Storing + * a double (%lf) uses two records, so this is quite costly. Use float (%f) + * unless the higher precision is really necessary. + * + * Note that the double-precision float (%lf) assumes a 64 bit double + * representation. This does not seem to be the case on e.g. PIC24 and PIC32. + * Before using a %lf argument on a 16-bit MCU, please verify that + * "sizeof(double)" actually gives 8 as expected. If not, use %f instead. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +void vTracePrintF(traceString eventLabel, const char* formatStr, ...) +{ + va_list vl; + + va_start(vl, formatStr); + vTracePrintF_Helper(eventLabel, formatStr, vl); + va_end(vl); +} +#endif + +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +void vTracePrintF_Helper(traceString eventLabel, const char* formatStr, va_list vl) +{ +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0) + uint32_t noOfSlots; + UserEvent* ue1; + uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4]; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(formatStr != NULL, "vTracePrintF_Helper: formatStr == NULL", TRC_UNUSED); + + trcCRITICAL_SECTION_BEGIN(); + + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + /* First, write the "primary" user event entry in the local buffer, but + let the event type be "EVENT_BEING_WRITTEN" for now...*/ + + ue1 = (UserEvent*)(&tempDataBuffer[0]); + + ue1->type = EVENT_BEING_WRITTEN; /* Update this as the last step */ + + noOfSlots = prvTraceUserEventFormat(formatStr, vl, (uint8_t*)tempDataBuffer, 4); + + /* Store the format string, with a reference to the channel symbol */ + ue1->payload = prvTraceOpenSymbol(formatStr, eventLabel); + + ue1->dts = (uint8_t)prvTraceGetDTS(0xFF); + + /* prvTraceGetDTS might stop the recorder in some cases... */ + if (RecorderDataPtr->recorderActive) + { + + /* If the data does not fit in the remaining main buffer, wrap around to + 0 if allowed, otherwise stop the recorder and quit). */ + if (RecorderDataPtr->nextFreeIndex + noOfSlots > RecorderDataPtr->maxEvents) + { + #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + (void)memset(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4], + 0, + (RecorderDataPtr->maxEvents - RecorderDataPtr->nextFreeIndex)*4); + RecorderDataPtr->nextFreeIndex = 0; + RecorderDataPtr->bufferIsFull = 1; + #else + + /* Stop recorder, since the event data will not fit in the + buffer and not circular buffer in this case... */ + vTraceStop(); + #endif + } + + /* Check if recorder has been stopped (i.e., vTraceStop above) */ + if (RecorderDataPtr->recorderActive) + { + /* Check that the buffer to be overwritten does not contain any user + events that would be partially overwritten. If so, they must be "killed" + by replacing the user event and following data with NULL events (i.e., + using a memset to zero).*/ + #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + prvCheckDataToBeOverwrittenForMultiEntryEvents((uint8_t)noOfSlots); + #endif + /* Copy the local buffer to the main buffer */ + (void)memcpy(& RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4], + tempDataBuffer, + noOfSlots * 4); + + /* Update the event type, i.e., number of data entries following the + main USER_EVENT entry (Note: important that this is after the memcpy, + but within the critical section!)*/ + RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex * 4] = + (uint8_t) ( USER_EVENT + noOfSlots - 1 ); + + /* Update the main buffer event index (already checked that it fits in + the buffer, so no need to check for wrapping)*/ + + RecorderDataPtr->nextFreeIndex += noOfSlots; + RecorderDataPtr->numEvents += noOfSlots; + + if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE) + { + #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + /* We have reached the end, but this is a ring buffer. Start from the beginning again. */ + RecorderDataPtr->bufferIsFull = 1; + RecorderDataPtr->nextFreeIndex = 0; + #else + /* We have reached the end so we stop. */ + vTraceStop(); + #endif + } + } + + #if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + /* Make sure the next entry is cleared correctly */ + prvCheckDataToBeOverwrittenForMultiEntryEvents(1); + #endif + + } + } + trcCRITICAL_SECTION_END(); + +#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) + /* Use the separate user event buffer */ + traceString formatLabel; + traceUBChannel channel; + + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + formatLabel = xTraceRegisterString(formatStr); + + channel = xTraceRegisterUBChannel(eventLabel, formatLabel); + + prvTraceUBHelper1(channel, eventLabel, formatLabel, vl); + } +#endif +} +#endif + +/****************************************************************************** + * vTracePrint + * + * Basic user event + * + * Generates a User Event with a text label. The label is created/looked up + * in the symbol table using xTraceRegisterString. + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +void vTracePrint(traceString chn, const char* str) +{ +#if (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 0) + UserEvent* ue; + uint8_t dts1; + TRACE_ALLOC_CRITICAL_SECTION(); + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + dts1 = (uint8_t)prvTraceGetDTS(0xFF); + ue = (UserEvent*) prvTraceNextFreeEventBufferSlot(); + if (ue != NULL) + { + ue->dts = dts1; + ue->type = USER_EVENT; + ue->payload = prvTraceOpenSymbol(str, chn); + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); + +#elif (TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER == 1) + traceUBChannel channel; + uint32_t noOfSlots = 1; + uint32_t tempDataBuffer[(3 + MAX_ARG_SIZE) / 4]; + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + traceString trcStr = prvTraceOpenSymbol(str, chn); + channel = xTraceRegisterUBChannel(chn, trcStr); + + if (channel == 0) + { + /* We are dealing with an unknown channel format pair */ + noOfSlots++; /* Also need room for channel and format */ + ((uint16_t*)tempDataBuffer)[2] = chn; + ((uint16_t*)tempDataBuffer)[3] = trcStr; + } + + prvTraceUBHelper2(channel, tempDataBuffer, noOfSlots); + } +#endif +} +#endif + +/******************************************************************************* + * xTraceRegisterString + * + * Register strings in the recorder, e.g. for names of user event channels. + * + * Example: + * myEventHandle = xTraceRegisterString("MyUserEvent"); + * ... + * vTracePrintF(myEventHandle, "My value is: %d", myValue); + ******************************************************************************/ +#if ((TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1)) +traceString xTraceRegisterString(const char* label) +{ + TRACE_ASSERT(label != NULL, "xTraceRegisterString: label == NULL", (traceString)0); + + return prvTraceOpenSymbol(label, 0); +} +#endif + + +#if ((!defined TRC_CFG_INCLUDE_READY_EVENTS) || (TRC_CFG_INCLUDE_READY_EVENTS == 1)) + +void prvTraceSetReadyEventsEnabled(int status) +{ + readyEventsEnabled = status; +} + +/******************************************************************************* + * prvTraceStoreTaskReady + * + * This function stores a ready state for the task handle sent in as parameter. + ******************************************************************************/ +void prvTraceStoreTaskReady(traceHandle handle) +{ + uint16_t dts3; + TREvent* tr; + uint8_t hnd8; + + TRACE_ALLOC_CRITICAL_SECTION(); + + if (handle == 0) + { + /* On FreeRTOS v7.3.0, this occurs when creating tasks due to a bad + placement of the trace macro. In that case, the events are ignored. */ + return; + } + + if (! readyEventsEnabled) + { + /* When creating tasks, ready events are also created. If creating + a "hidden" (not traced) task, we must therefore disable recording + of ready events to avoid an undesired ready event... */ + return; + } + + TRACE_ASSERT(handle <= TRC_CFG_NTASK, "prvTraceStoreTaskReady: Invalid value for handle", TRC_UNUSED); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("Recorder busy - high priority ISR using syscall? (1)"); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive) /* Need to repeat this check! */ + { + dts3 = (uint16_t)prvTraceGetDTS(0xFFFF); + hnd8 = prvTraceGet8BitHandle(handle); + tr = (TREvent*)prvTraceNextFreeEventBufferSlot(); + if (tr != NULL) + { + tr->type = DIV_TASK_READY; + tr->dts = dts3; + tr->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} +#endif + +/******************************************************************************* + * prvTraceStoreLowPower + * + * This function stores a low power state. + ******************************************************************************/ +void prvTraceStoreLowPower(uint32_t flag) +{ + uint16_t dts; + LPEvent* lp; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(flag <= 1, "prvTraceStoreLowPower: Invalid flag value", TRC_UNUSED); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("Recorder busy - high priority ISR using syscall? (1)"); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive) + { + dts = (uint16_t)prvTraceGetDTS(0xFFFF); + lp = (LPEvent*)prvTraceNextFreeEventBufferSlot(); + if (lp != NULL) + { + lp->type = (uint8_t) (LOW_POWER_BEGIN + ( uint8_t ) flag); /* BEGIN or END depending on flag */ + lp->dts = dts; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} + +/******************************************************************************* + * vTraceStoreMemMangEvent + * + * This function stores malloc and free events. Each call requires two records, + * for size and address respectively. The event code parameter (ecode) is applied + * to the first record (size) and the following address record gets event + * code "ecode + 1", so make sure this is respected in the event code table. + * Note: On "free" calls, the signed_size parameter should be negative. + ******************************************************************************/ +#if (TRC_CFG_INCLUDE_MEMMANG_EVENTS == 1) +#if (TRC_CFG_SCHEDULING_ONLY == 0) +void vTraceStoreMemMangEvent(uint32_t ecode, uint32_t address, int32_t signed_size) +{ + uint8_t dts1; + MemEventSize * ms; + MemEventAddr * ma; + uint16_t size_low; + uint16_t addr_low; + uint8_t addr_high; + uint32_t size; + TRACE_ALLOC_CRITICAL_SECTION(); + + if (RecorderDataPtr == NULL) + { + /* Occurs in vTraceInitTraceData, if using dynamic allocation. */ + return; + } + + if (signed_size < 0) + size = (uint32_t)(- signed_size); + else + size = (uint32_t)(signed_size); + + trcCRITICAL_SECTION_BEGIN(); + + heapMemUsage = heapMemUsage + (uint32_t)signed_size; + + if (RecorderDataPtr->recorderActive) + { + dts1 = (uint8_t)prvTraceGetDTS(0xFF); + size_low = (uint16_t)prvTraceGetParam(0xFFFF, size); + ms = (MemEventSize *)prvTraceNextFreeEventBufferSlot(); + + if (ms != NULL) + { + ms->dts = dts1; + ms->type = NULL_EVENT; /* Updated when all events are written */ + ms->size = size_low; + prvTraceUpdateCounters(); + + /* Storing a second record with address (signals "failed" if null) */ + #if (TRC_CFG_HEAP_SIZE_BELOW_16M) + /* If the heap address range is within 16 MB, i.e., the upper 8 bits + of addresses are constant, this optimization avoids storing an extra + event record by ignoring the upper 8 bit of the address */ + addr_low = address & 0xFFFF; + addr_high = (address >> 16) & 0xFF; + #else + /* The whole 32 bit address is stored using a second event record + for the upper 16 bit */ + addr_low = (uint16_t)prvTraceGetParam(0xFFFF, address); + addr_high = 0; + #endif + + ma = (MemEventAddr *) prvTraceNextFreeEventBufferSlot(); + if (ma != NULL) + { + ma->addr_low = addr_low; + ma->addr_high = addr_high; + ma->type = (uint8_t) (ecode + 1); /* Note this! */ + ms->type = (uint8_t) ecode; + prvTraceUpdateCounters(); + RecorderDataPtr->heapMemUsage = heapMemUsage; + } + } + } + trcCRITICAL_SECTION_END(); +} +#endif /* TRC_CFG_SCHEDULING_ONLY */ +#endif + +/******************************************************************************* + * prvTraceStoreKernelCall + * + * This is the main integration point for storing kernel calls, and + * is called by the hooks in trcKernelHooks.h (see trcKernelPort.h for event codes). + ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) +void prvTraceStoreKernelCall(uint32_t ecode, traceObjectClass objectClass, uint32_t objectNumber) +{ + KernelCall * kse; + uint16_t dts1; + uint8_t hnd8; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(ecode < 0xFF, "prvTraceStoreKernelCall: ecode >= 0xFF", TRC_UNUSED); + TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCall: objectClass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCall: Invalid value for objectNumber", TRC_UNUSED); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("Recorder busy - high priority ISR using syscall? (2)"); + return; + } + + if (handle_of_last_logged_task == 0) + { + return; + } + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive) + { + dts1 = (uint16_t)prvTraceGetDTS(0xFFFF); + hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); + kse = (KernelCall*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) + { + kse->dts = dts1; + kse->type = (uint8_t)ecode; + kse->objHandle = hnd8; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} +#endif /* TRC_CFG_SCHEDULING_ONLY */ + +/******************************************************************************* + * prvTraceStoreKernelCallWithParam + * + * Used for storing kernel calls with a handle and a numeric parameter. If the + * numeric parameter does not fit in one byte, and extra XPS event is inserted + * before the kernel call event containing the three upper bytes. + ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) +void prvTraceStoreKernelCallWithParam(uint32_t evtcode, + traceObjectClass objectClass, + uint32_t objectNumber, + uint32_t param) +{ + KernelCallWithParamAndHandle * kse; + uint8_t dts2; + uint8_t hnd8; + uint8_t p8; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithParam: evtcode >= 0xFF", TRC_UNUSED); + TRACE_ASSERT(objectClass < TRACE_NCLASSES, "prvTraceStoreKernelCallWithParam: objectClass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(objectNumber <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectClass], "prvTraceStoreKernelCallWithParam: Invalid value for objectNumber", TRC_UNUSED); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("Recorder busy - high priority ISR using syscall? (3)"); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + dts2 = (uint8_t)prvTraceGetDTS(0xFF); + p8 = (uint8_t) prvTraceGetParam(0xFF, param); + hnd8 = prvTraceGet8BitHandle((traceHandle)objectNumber); + kse = (KernelCallWithParamAndHandle*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) + { + kse->dts = dts2; + kse->type = (uint8_t)evtcode; + kse->objHandle = hnd8; + kse->param = p8; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} +#endif /* TRC_CFG_SCHEDULING_ONLY */ + + +/******************************************************************************* + * prvTraceGetParam + * + * Used for storing extra bytes for kernel calls with numeric parameters. + * + * May only be called within a critical section! + ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) +static uint32_t prvTraceGetParam(uint32_t param_max, uint32_t param) +{ + XPSEvent* xps; + + TRACE_ASSERT(param_max == 0xFF || param_max == 0xFFFF, + "prvTraceGetParam: Invalid value for param_max", param); + + if (param <= param_max) + { + return param; + } + else + { + xps = (XPSEvent*) prvTraceNextFreeEventBufferSlot(); + if (xps != NULL) + { + xps->type = DIV_XPS; + xps->xps_8 = (uint8_t)((param & (0xFF00 & ~param_max)) >> 8); + xps->xps_16 = (uint16_t)((param & (0xFFFF0000 & ~param_max)) >> 16); + prvTraceUpdateCounters(); + } + + return param & param_max; + } +} +#endif + +/******************************************************************************* + * prvTraceStoreKernelCallWithNumericParamOnly + * + * Used for storing kernel calls with numeric parameters only. This is + * only used for traceTASK_DELAY and traceDELAY_UNTIL at the moment. + ******************************************************************************/ +#if (TRC_CFG_SCHEDULING_ONLY == 0) +void prvTraceStoreKernelCallWithNumericParamOnly(uint32_t evtcode, uint32_t param) +{ + KernelCallWithParam16 * kse; + uint8_t dts6; + uint16_t restParam; + TRACE_ALLOC_CRITICAL_SECTION(); + + restParam = 0; + + TRACE_ASSERT(evtcode < 0xFF, "prvTraceStoreKernelCallWithNumericParamOnly: Invalid value for evtcode", TRC_UNUSED); + + if (recorder_busy) + { + /************************************************************************* + * This occurs if an ISR calls a trace function, preempting a previous + * trace call that is being processed in a different ISR or task. + * If this occurs, there is probably a problem in the definition of the + * recorder's internal critical sections (TRACE_ENTER_CRITICAL_SECTION and + * TRACE_EXIT_CRITICAL_SECTION). They must disable the RTOS tick interrupt + * and any other ISRs that calls the trace recorder directly or via + * traced kernel functions. The ARM port disables all interrupts using the + * PRIMASK register to avoid this issue. + *************************************************************************/ + prvTraceError("Recorder busy - high priority ISR using syscall? (4)"); + return; + } + + trcCRITICAL_SECTION_BEGIN(); + if (RecorderDataPtr->recorderActive && handle_of_last_logged_task) + { + dts6 = (uint8_t)prvTraceGetDTS(0xFF); + restParam = (uint16_t)prvTraceGetParam(0xFFFF, param); + kse = (KernelCallWithParam16*) prvTraceNextFreeEventBufferSlot(); + if (kse != NULL) + { + kse->dts = dts6; + kse->type = (uint8_t)evtcode; + kse->param = restParam; + prvTraceUpdateCounters(); + } + } + trcCRITICAL_SECTION_END(); +} +#endif /* TRC_CFG_SCHEDULING_ONLY */ + +/******************************************************************************* + * prvTraceStoreTaskswitch + * Called by the scheduler from the SWITCHED_OUT hook, and by uiTraceStart. + * At this point interrupts are assumed to be disabled! + ******************************************************************************/ +void prvTraceStoreTaskswitch(traceHandle task_handle) +{ + uint16_t dts3; + TSEvent* ts; + uint8_t hnd8; +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) + extern int32_t isPendingContextSwitch; +#endif + trcSR_ALLOC_CRITICAL_SECTION_ON_CORTEX_M_ONLY(); + + TRACE_ASSERT(task_handle <= TRC_CFG_NTASK, + "prvTraceStoreTaskswitch: Invalid value for task_handle", TRC_UNUSED); + + trcCRITICAL_SECTION_BEGIN_ON_CORTEX_M_ONLY(); + + if ((task_handle != handle_of_last_logged_task) && (RecorderDataPtr->recorderActive)) + { +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) + isPendingContextSwitch = 0; +#endif + + dts3 = (uint16_t)prvTraceGetDTS(0xFFFF); + handle_of_last_logged_task = task_handle; + hnd8 = prvTraceGet8BitHandle(handle_of_last_logged_task); + ts = (TSEvent*)prvTraceNextFreeEventBufferSlot(); + + if (ts != NULL) + { + if (prvTraceGetObjectState(TRACE_CLASS_TASK, + handle_of_last_logged_task) == TASK_STATE_INSTANCE_ACTIVE) + { + ts->type = TS_TASK_RESUME; + } + else + { + ts->type = TS_TASK_BEGIN; + } + + ts->dts = dts3; + ts->objHandle = hnd8; + + prvTraceSetObjectState(TRACE_CLASS_TASK, + handle_of_last_logged_task, + TASK_STATE_INSTANCE_ACTIVE); + + prvTraceUpdateCounters(); + } + } + + trcCRITICAL_SECTION_END_ON_CORTEX_M_ONLY(); +} + +/******************************************************************************* + * prvTraceStoreObjectNameOnCloseEvent + * + * Updates the symbol table with the name of this object from the dynamic + * objects table and stores a "close" event, holding the mapping between handle + * and name (a symbol table handle). The stored name-handle mapping is thus the + * "old" one, valid up until this point. + ******************************************************************************/ +void prvTraceStoreObjectNameOnCloseEvent(uint8_t evtcode, traceHandle handle, + traceObjectClass objectclass) +{ + ObjCloseNameEvent * ce; + const char * name; + traceString idx; + + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceStoreObjectNameOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceStoreObjectNameOnCloseEvent: Invalid value for handle", TRC_UNUSED); + + if (RecorderDataPtr->recorderActive) + { + uint8_t hnd8 = prvTraceGet8BitHandle(handle); + name = TRACE_PROPERTY_NAME_GET(objectclass, handle); + idx = prvTraceOpenSymbol(name, 0); + + // Interrupt disable not necessary, already done in trcHooks.h macro + ce = (ObjCloseNameEvent*) prvTraceNextFreeEventBufferSlot(); + if (ce != NULL) + { + ce->type = (uint8_t) evtcode; + ce->objHandle = hnd8; + ce->symbolIndex = idx; + prvTraceUpdateCounters(); + } + } +} + +void prvTraceStoreObjectPropertiesOnCloseEvent(uint8_t evtcode, traceHandle handle, + traceObjectClass objectclass) +{ + ObjClosePropEvent * pe; + + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceStoreObjectPropertiesOnCloseEvent: objectclass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceStoreObjectPropertiesOnCloseEvent: Invalid value for handle", TRC_UNUSED); + + if (RecorderDataPtr->recorderActive) + { + // Interrupt disable not necessary, already done in trcHooks.h macro + pe = (ObjClosePropEvent*) prvTraceNextFreeEventBufferSlot(); + if (pe != NULL) + { + if (objectclass == TRACE_CLASS_TASK) + { + pe->arg1 = TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, handle); + } + else + { + pe->arg1 = TRACE_PROPERTY_OBJECT_STATE(objectclass, handle); + } + pe->type = evtcode; + prvTraceUpdateCounters(); + } + } +} + +void prvTraceSetPriorityProperty(uint8_t objectclass, traceHandle id, uint8_t value) +{ + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceSetPriorityProperty: objectclass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceSetPriorityProperty: Invalid value for id", TRC_UNUSED); + + TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id) = value; +} + +uint8_t prvTraceGetPriorityProperty(uint8_t objectclass, traceHandle id) +{ + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceGetPriorityProperty: objectclass >= TRACE_NCLASSES", 0); + TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceGetPriorityProperty: Invalid value for id", 0); + + return TRACE_PROPERTY_ACTOR_PRIORITY(objectclass, id); +} + +void prvTraceSetObjectState(uint8_t objectclass, traceHandle id, uint8_t value) +{ + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceSetObjectState: objectclass >= TRACE_NCLASSES", TRC_UNUSED); + TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceSetObjectState: Invalid value for id", TRC_UNUSED); + + TRACE_PROPERTY_OBJECT_STATE(objectclass, id) = value; +} + +uint8_t prvTraceGetObjectState(uint8_t objectclass, traceHandle id) +{ + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceGetObjectState: objectclass >= TRACE_NCLASSES", 0); + TRACE_ASSERT(id <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceGetObjectState: Invalid value for id", 0); + + return TRACE_PROPERTY_OBJECT_STATE(objectclass, id); +} + +void prvTraceSetTaskInstanceFinished(traceHandle handle) +{ + TRACE_ASSERT(handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[TRACE_CLASS_TASK], + "prvTraceSetTaskInstanceFinished: Invalid value for handle", TRC_UNUSED); + +#if (TRC_CFG_USE_IMPLICIT_IFE_RULES == 1) + TRACE_PROPERTY_OBJECT_STATE(TRACE_CLASS_TASK, handle) = 0; +#endif +} + +/******************************************************************************* + * Static data initializations + ******************************************************************************/ + +/* A set of stacks that keeps track of available object handles for each class. +The stacks are empty initially, meaning that allocation of new handles will be +based on a counter (for each object class). Any delete operation will +return the handle to the corresponding stack, for reuse on the next allocate.*/ +objectHandleStackType objectHandleStacks = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } }; + +/* Initial TRC_HWTC_COUNT value, for detecting if the time-stamping source is +enabled. If using the OS periodic timer for time-stamping, this might not +have been configured on the earliest events during the startup. */ +uint32_t init_hwtc_count; + +/******************************************************************************* + * RecorderData + * + * The main data structure in snapshot mode, when using the default static memory + * allocation (TRC_RECORDER_BUFFER_ALLOCATION_STATIC). The recorder uses a pointer + * RecorderDataPtr to access the data, to also allow for dynamic or custom data + * allocation (see TRC_CFG_RECORDER_BUFFER_ALLOCATION). + ******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) +RecorderDataType RecorderData; +#endif + +/******************************************************************************* + * RecorderDataPtr + * + * Pointer to the main data structure, when in snapshot mode. + ******************************************************************************/ +RecorderDataType* RecorderDataPtr = NULL; + +/* This version of the function dynamically allocates the trace data */ +void prvTraceInitTraceData() +{ + + if (RecorderDataPtr == NULL) + { +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC) + RecorderDataPtr = &RecorderData; +#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC) + RecorderDataPtr = (RecorderDataType*)TRACE_MALLOC(sizeof(RecorderDataType)); + if (! RecorderDataPtr) + { + prvTraceError("Failed allocating recorder buffer!"); + return; + } +#elif (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) + if (! RecorderDataPtr) + { + prvTraceError("Recorder data pointer not set! Use vTraceSetRecorderDataBuffer()."); + return; + } +#endif + } + else + { + if (RecorderDataPtr->startmarker0 == 1) + { + /* Already initialized */ + return; + } + } + + init_hwtc_count = TRC_HWTC_COUNT; + + (void)memset(RecorderDataPtr, 0, sizeof(RecorderDataType)); + + RecorderDataPtr->version = TRACE_KERNEL_VERSION; + RecorderDataPtr->minor_version = TRACE_MINOR_VERSION; + RecorderDataPtr->irq_priority_order = TRC_IRQ_PRIORITY_ORDER; + RecorderDataPtr->filesize = sizeof(RecorderDataType); + RecorderDataPtr->maxEvents = TRC_CFG_EVENT_BUFFER_SIZE; + RecorderDataPtr->debugMarker0 = (int32_t) 0xF0F0F0F0; + RecorderDataPtr->isUsing16bitHandles = TRC_CFG_USE_16BIT_OBJECT_HANDLES; + RecorderDataPtr->isrTailchainingThreshold = TRC_CFG_ISR_TAILCHAINING_THRESHOLD; + + /* This function is kernel specific */ + vTraceInitObjectPropertyTable(); + + RecorderDataPtr->debugMarker1 = (int32_t)0xF1F1F1F1; + RecorderDataPtr->SymbolTable.symTableSize = TRC_CFG_SYMBOL_TABLE_SIZE; + RecorderDataPtr->SymbolTable.nextFreeSymbolIndex = 1; +#if (TRC_CFG_INCLUDE_FLOAT_SUPPORT == 1) + RecorderDataPtr->exampleFloatEncoding = 1.0f; /* otherwise already zero */ +#endif + RecorderDataPtr->debugMarker2 = (int32_t)0xF2F2F2F2; +#if 0 + prvStrncpy(RecorderDataPtr->systemInfo, "Trace Recorder Demo", 80); +#else /* << EST */ + prvStrncpy(RecorderDataPtr->systemInfo, TRC_CFG_TRACE_DESCRIPTION, TRC_CFG_TRACE_DESCRIPTION_MAX_LENGTH); /* << EST */ +#endif + RecorderDataPtr->debugMarker3 = (int32_t)0xF3F3F3F3; + RecorderDataPtr->endmarker0 = 0x0A; + RecorderDataPtr->endmarker1 = 0x0B; + RecorderDataPtr->endmarker2 = 0x0C; + RecorderDataPtr->endmarker3 = 0x0D; + RecorderDataPtr->endmarker4 = 0x71; + RecorderDataPtr->endmarker5 = 0x72; + RecorderDataPtr->endmarker6 = 0x73; + RecorderDataPtr->endmarker7 = 0x74; + RecorderDataPtr->endmarker8 = 0xF1; + RecorderDataPtr->endmarker9 = 0xF2; + RecorderDataPtr->endmarker10 = 0xF3; + RecorderDataPtr->endmarker11 = 0xF4; + +#if TRC_CFG_USE_SEPARATE_USER_EVENT_BUFFER + RecorderDataPtr->userEventBuffer.bufferID = 1; + RecorderDataPtr->userEventBuffer.version = 0; + RecorderDataPtr->userEventBuffer.numberOfSlots = TRC_CFG_SEPARATE_USER_EVENT_BUFFER_SIZE; + RecorderDataPtr->userEventBuffer.numberOfChannels = TRC_CFG_UB_CHANNELS + 1; +#endif + + /* Kernel specific initialization of the objectHandleStacks variable */ + vTraceInitObjectHandleStack(); + + + /* Finally, the 12-byte "start markers" are initialized, allowing for + Tracealyzer to find the trace data in a larger RAM dump. + + The start and end markers must be unique, but without proper precautions there + might be a risk of accidental duplicates of the start/end markers, e.g., due to + compiler optimizations. + + The below initialization of the start marker is therefore made in reverse order + and the fields are volatile to ensure this assignment order. This to avoid any + chance of accidental duplicates of this elsewhere in memory. + + Moreover, the fields are set byte-by-byte to avoid endian issues.*/ + + RecorderDataPtr->startmarker11 = 0xF4; + RecorderDataPtr->startmarker10 = 0xF3; + RecorderDataPtr->startmarker9 = 0xF2; + RecorderDataPtr->startmarker8 = 0xF1; + RecorderDataPtr->startmarker7 = 0x74; + RecorderDataPtr->startmarker6 = 0x73; + RecorderDataPtr->startmarker5 = 0x72; + RecorderDataPtr->startmarker4 = 0x71; + RecorderDataPtr->startmarker3 = 0x04; + RecorderDataPtr->startmarker2 = 0x03; + RecorderDataPtr->startmarker1 = 0x02; + RecorderDataPtr->startmarker0 = 0x01; + + +#ifdef TRC_PORT_SPECIFIC_INIT + TRC_PORT_SPECIFIC_INIT(); +#endif +} + + +void* prvTraceNextFreeEventBufferSlot(void) +{ + if (! RecorderDataPtr->recorderActive) + { + /* If an XTS or XPS event prior to the main event has filled the buffer + before saving the main event, and store mode is "stop when full". */ + return NULL; + } + + if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE) + { + prvTraceError("Attempt to index outside event buffer!"); + return NULL; + } + return (void*)(&RecorderDataPtr->eventData[RecorderDataPtr->nextFreeIndex*4]); +} + +uint16_t uiIndexOfObject(traceHandle objecthandle, uint8_t objectclass) +{ + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "uiIndexOfObject: Invalid value for objectclass", 0); + TRACE_ASSERT(objecthandle > 0 && objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "uiIndexOfObject: Invalid value for objecthandle", 0); + + if ((objectclass < TRACE_NCLASSES) && (objecthandle > 0) && + (objecthandle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass])) + { + return (uint16_t)(RecorderDataPtr->ObjectPropertyTable.StartIndexOfClass[objectclass] + + (RecorderDataPtr->ObjectPropertyTable.TotalPropertyBytesPerClass[objectclass] * (objecthandle-1))); + } + + prvTraceError("Object table lookup with invalid object handle or object class!"); + return 0; +} + +traceHandle prvTraceGetObjectHandle(traceObjectClass objectclass) +{ + traceHandle handle; + static int indexOfHandle; + + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceGetObjectHandle: Invalid value for objectclass", (traceHandle)0); + + trcCRITICAL_SECTION_BEGIN(); + indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; + if (objectHandleStacks.objectHandles[indexOfHandle] == 0) + { + /* Zero is used to indicate a never before used handle, i.e., + new slots in the handle stack. The handle slot needs to + be initialized here (starts at 1). */ + objectHandleStacks.objectHandles[indexOfHandle] = + (traceHandle)(1 + indexOfHandle - + objectHandleStacks.lowestIndexOfClass[objectclass]); + } + + handle = objectHandleStacks.objectHandles[indexOfHandle]; + + if (objectHandleStacks.indexOfNextAvailableHandle[objectclass] + > objectHandleStacks.highestIndexOfClass[objectclass]) + { + prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass)); + handle = 0; + } + else + { + int hndCount; + objectHandleStacks.indexOfNextAvailableHandle[objectclass]++; + + hndCount = objectHandleStacks.indexOfNextAvailableHandle[objectclass] - + objectHandleStacks.lowestIndexOfClass[objectclass]; + + if (hndCount > + objectHandleStacks.handleCountWaterMarksOfClass[objectclass]) + { + objectHandleStacks.handleCountWaterMarksOfClass[objectclass] = + (traceHandle)hndCount; + } + } + trcCRITICAL_SECTION_END(); + + return handle; +} + +void prvTraceFreeObjectHandle(traceObjectClass objectclass, traceHandle handle) +{ + int indexOfHandle; + + TRACE_ASSERT(objectclass < TRACE_NCLASSES, + "prvTraceFreeObjectHandle: Invalid value for objectclass", TRC_UNUSED); + TRACE_ASSERT(handle > 0 && handle <= RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass], + "prvTraceFreeObjectHandle: Invalid value for handle", TRC_UNUSED); + + /* Check that there is room to push the handle on the stack */ + if ((objectHandleStacks.indexOfNextAvailableHandle[objectclass] - 1) < + objectHandleStacks.lowestIndexOfClass[objectclass]) + { + /* Error */ + prvTraceError("Attempt to free more handles than allocated!"); + } + else + { + objectHandleStacks.indexOfNextAvailableHandle[objectclass]--; + indexOfHandle = objectHandleStacks.indexOfNextAvailableHandle[objectclass]; + objectHandleStacks.objectHandles[indexOfHandle] = handle; + } +} + +/******************************************************************************* + * prvMarkObjectAsUsed + * + * Sets an "is used flag" on object creation, using the first byte of the name + * field. This allows for counting the number of used Object Table slots, even + * if no names have been set. + ******************************************************************************/ +void prvMarkObjectAsUsed(traceObjectClass objectclass, traceHandle handle) +{ + uint16_t idx = uiIndexOfObject(handle, objectclass); + RecorderDataPtr->ObjectPropertyTable.objbytes[idx] = 1; +} + +/******************************************************************************* + * prvStrncpy + * + * Private string copy function, to improve portability between compilers. + ******************************************************************************/ +static void prvStrncpy(char* dst, const char* src, uint32_t maxLength) +{ + uint32_t i; + for (i = 0; i < maxLength; i++) + { + dst[i] = src[i]; + if (src[i] == 0) + break; + } +} + +/******************************************************************************* + * prvTraceSetObjectName + * + * Registers the names of queues, semaphores and other kernel objects in the + * recorder's Object Property Table, at the given handle and object class. + ******************************************************************************/ +void prvTraceSetObjectName(traceObjectClass objectclass, + traceHandle handle, + const char* name) +{ + static uint16_t idx; + + TRACE_ASSERT(name != NULL, "prvTraceSetObjectName: name == NULL", TRC_UNUSED); + + if (objectclass >= TRACE_NCLASSES) + { + prvTraceError("Illegal object class in prvTraceSetObjectName"); + return; + } + + if (handle == 0) + { + prvTraceError("Illegal handle (0) in prvTraceSetObjectName."); + return; + } + + if (handle > RecorderDataPtr->ObjectPropertyTable.NumberOfObjectsPerClass[objectclass]) + { + /* ERROR */ + prvTraceError(pszTraceGetErrorNotEnoughHandles(objectclass)); + } + else + { + idx = uiIndexOfObject(handle, objectclass); + + if (traceErrorMessage == NULL) + { + prvStrncpy((char*)&(RecorderDataPtr->ObjectPropertyTable.objbytes[idx]), + name, + RecorderDataPtr->ObjectPropertyTable.NameLengthPerClass[ objectclass ]); + } + } +} + +traceString prvTraceOpenSymbol(const char* name, traceString userEventChannel) +{ + uint16_t result; + uint8_t len; + uint8_t crc; + TRACE_ALLOC_CRITICAL_SECTION(); + + len = 0; + crc = 0; + + TRACE_ASSERT(name != NULL, "prvTraceOpenSymbol: name == NULL", (traceString)0); + + prvTraceGetChecksum(name, &crc, &len); + + trcCRITICAL_SECTION_BEGIN(); + result = prvTraceLookupSymbolTableEntry(name, crc, len, userEventChannel); + if (!result) + { + result = prvTraceCreateSymbolTableEntry(name, crc, len, userEventChannel); + } + trcCRITICAL_SECTION_END(); + + return result; +} + + +/****************************************************************************** +* vTraceSetFrequency +* +* Registers the clock rate of the time source for the event timestamping. +* This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ) +* should be incorrect for your setup, you can override it using this function. +* +* Must be called prior to vTraceEnable, and the time source is assumed to +* have a fixed clock frequency after the startup. +* +* Note that, in snapshot mode, the value is divided by the TRC_HWTC_DIVISOR. +* This is a software "prescaler" that is also applied on the timestamps. +*****************************************************************************/ +void vTraceSetFrequency(uint32_t frequency) +{ + timestampFrequency = frequency; +} + +/******************************************************************************* + * Supporting functions + ******************************************************************************/ + +/******************************************************************************* + * prvTraceError + * + * Called by various parts in the recorder. Stops the recorder and stores a + * pointer to an error message, which is printed by the monitor task. + * If you are not using the monitor task, you may use xTraceGetLastError() + * from your application to check if the recorder is OK. + * + * Note: If a recorder error is registered before vTraceStart is called, the + * trace start will be aborted. This can occur if any of the Nxxxx constants + * (e.g., TRC_CFG_NTASK) in trcConfig.h is too small. + ******************************************************************************/ +void prvTraceError(const char* msg) +{ + /* Stop the recorder */ + if (RecorderDataPtr != NULL) + { + vTraceStop(); + } + + /* If first error only... */ + if (traceErrorMessage == NULL) + { + traceErrorMessage = (char*)(intptr_t) msg; + if (RecorderDataPtr != NULL) + { + prvStrncpy(RecorderDataPtr->systemInfo, traceErrorMessage, 80); + RecorderDataPtr->internalErrorOccured = 1; + } + } +} + +void vTraceSetFilterMask(uint16_t filterMask) +{ + CurrentFilterMask = filterMask; +} + +void vTraceSetFilterGroup(uint16_t filterGroup) +{ + CurrentFilterGroup = filterGroup; +} + +/****************************************************************************** + * prvCheckDataToBeOverwrittenForMultiEntryEvents + * + * This checks if the next event to be overwritten is a multi-entry user event, + * i.e., a USER_EVENT followed by data entries. + * Such data entries do not have an event code at byte 0, as other events. + * All 4 bytes are user data, so the first byte of such data events must + * not be interpreted as type field. The number of data entries following + * a USER_EVENT is given in the event code of the USER_EVENT. + * Therefore, when overwriting a USER_EVENT (when using in ring-buffer mode) + * any data entries following must be replaced with NULL events (code 0). + * + * This is assumed to execute within a critical section... + *****************************************************************************/ + +#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) +void prvCheckDataToBeOverwrittenForMultiEntryEvents(uint8_t nofEntriesToCheck) +{ + /* Generic "int" type is desired - should be 16 bit variable on 16 bit HW */ + unsigned int i = 0; + unsigned int e = 0; + + TRACE_ASSERT(nofEntriesToCheck != 0, + "prvCheckDataToBeOverwrittenForMultiEntryEvents: nofEntriesToCheck == 0", TRC_UNUSED); + + while (i < nofEntriesToCheck) + { + e = RecorderDataPtr->nextFreeIndex + i; + if ((RecorderDataPtr->eventData[e*4] > USER_EVENT) && + (RecorderDataPtr->eventData[e*4] < USER_EVENT + 16)) + { + uint8_t nDataEvents = (uint8_t)(RecorderDataPtr->eventData[e*4] - USER_EVENT); + if ((e + nDataEvents) < RecorderDataPtr->maxEvents) + { + (void)memset(& RecorderDataPtr->eventData[e*4], 0, (size_t) (4 + 4 * nDataEvents)); + } + } + else if (RecorderDataPtr->eventData[e*4] == DIV_XPS) + { + if ((e + 1) < RecorderDataPtr->maxEvents) + { + /* Clear 8 bytes */ + (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4 + 4); + } + else + { + /* Clear 8 bytes, 4 first and 4 last */ + (void)memset(& RecorderDataPtr->eventData[0], 0, 4); + (void)memset(& RecorderDataPtr->eventData[e*4], 0, 4); + } + } + i++; + } +} +#endif + +/******************************************************************************* + * prvTraceUpdateCounters + * + * Updates the index of the event buffer. + ******************************************************************************/ +void prvTraceUpdateCounters(void) +{ + if (RecorderDataPtr->recorderActive == 0) + { + return; + } + + RecorderDataPtr->numEvents++; + + RecorderDataPtr->nextFreeIndex++; + + if (RecorderDataPtr->nextFreeIndex >= TRC_CFG_EVENT_BUFFER_SIZE) + { +#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + RecorderDataPtr->bufferIsFull = 1; + RecorderDataPtr->nextFreeIndex = 0; + { + void PTRC1_OnTraceWrap(void); /* prototype */ + + PTRC1_OnTraceWrap(); + } +#else + vTraceStop(); +#endif + } + +#if (TRC_CFG_SNAPSHOT_MODE == TRC_SNAPSHOT_MODE_RING_BUFFER) + prvCheckDataToBeOverwrittenForMultiEntryEvents(1); +#endif +} + +/****************************************************************************** + * prvTraceGetDTS + * + * Returns a differential timestamp (DTS), i.e., the time since + * last event, and creates an XTS event if the DTS does not fit in the + * number of bits given. The XTS event holds the MSB bytes of the DTS. + * + * The parameter param_maxDTS should be 0xFF for 8-bit dts or 0xFFFF for + * events with 16-bit dts fields. + *****************************************************************************/ +uint16_t prvTraceGetDTS(uint16_t param_maxDTS) +{ + static uint32_t old_timestamp = 0; + XTSEvent* xts = 0; + uint32_t dts = 0; + uint32_t timestamp = 0; + + TRACE_ASSERT(param_maxDTS == 0xFF || param_maxDTS == 0xFFFF, "prvTraceGetDTS: Invalid value for param_maxDTS", 0); + + + if (RecorderDataPtr->frequency == 0) + { + if (timestampFrequency != 0) + { + /* If to override default TRC_HWTC_FREQ_HZ value with value set by vTraceSetFrequency */ + RecorderDataPtr->frequency = timestampFrequency / TRC_HWTC_DIVISOR; + } + else if (init_hwtc_count != TRC_HWTC_COUNT) + { + /* If using default value and timer has been started. + Note: If the default frequency value set here would be incorrect, e.g., + if the timer has actually not been configured yet, override this + with vTraceSetFrequency. + */ + RecorderDataPtr->frequency = TRC_HWTC_FREQ_HZ / TRC_HWTC_DIVISOR; + } + /* If no override (vTraceSetFrequency) and timer inactive -> no action */ + } + + /************************************************************************** + * The below statements read the timestamp from the timer port module. + * If necessary, whole seconds are extracted using division while the rest + * comes from the modulo operation. + **************************************************************************/ + + prvTracePortGetTimeStamp(×tamp); + + /*************************************************************************** + * Since dts is unsigned the result will be correct even if timestamp has + * wrapped around. + ***************************************************************************/ + dts = timestamp - old_timestamp; + old_timestamp = timestamp; + + if (RecorderDataPtr->frequency > 0) + { + /* Check if dts > 1 second */ + if (dts > RecorderDataPtr->frequency) + { + /* More than 1 second has passed */ + RecorderDataPtr->absTimeLastEventSecond += dts / RecorderDataPtr->frequency; + /* The part that is not an entire second is added to absTimeLastEvent */ + RecorderDataPtr->absTimeLastEvent += dts % RecorderDataPtr->frequency; + } + else + { + RecorderDataPtr->absTimeLastEvent += dts; + } + + /* Check if absTimeLastEvent >= 1 second */ + if (RecorderDataPtr->absTimeLastEvent >= RecorderDataPtr->frequency) + { + /* RecorderDataPtr->absTimeLastEvent is more than or equal to 1 second, but always less than 2 seconds */ + RecorderDataPtr->absTimeLastEventSecond++; + RecorderDataPtr->absTimeLastEvent -= RecorderDataPtr->frequency; + /* RecorderDataPtr->absTimeLastEvent is now less than 1 second */ + } + } + else + { + /* Special case if the recorder has not yet started (frequency may be uninitialized, i.e., zero) */ + RecorderDataPtr->absTimeLastEvent = timestamp; + } + + /* If the dts (time since last event) does not fit in event->dts (only 8 or 16 bits) */ + if (dts > param_maxDTS) + { + /* Create an XTS event (eXtended TimeStamp) containing the higher dts bits*/ + xts = (XTSEvent*) prvTraceNextFreeEventBufferSlot(); + + if (xts != NULL) + { + if (param_maxDTS == 0xFFFF) + { + xts->type = XTS16; + xts->xts_16 = (uint16_t)((dts / 0x10000) & 0xFFFF); + xts->xts_8 = 0; + } + else if (param_maxDTS == 0xFF) + { + xts->type = XTS8; + xts->xts_16 = (uint16_t)((dts / 0x100) & 0xFFFF); + xts->xts_8 = (uint8_t)((dts / 0x1000000) & 0xFF); + } + else + { + prvTraceError("Bad param_maxDTS in prvTraceGetDTS"); + } + prvTraceUpdateCounters(); + } + } + + return (uint16_t)dts & param_maxDTS; +} + +/******************************************************************************* + * prvTraceLookupSymbolTableEntry + * + * Find an entry in the symbol table, return 0 if not present. + * + * The strings are stored in a byte pool, with four bytes of "meta-data" for + * every string. + * byte 0-1: index of next entry with same checksum (for fast lookup). + * byte 2-3: reference to a symbol table entry, a label for vTracePrintF + * format strings only (the handle of the destination channel). + * byte 4..(4 + length): the string (object name or user event label), with + * zero-termination + ******************************************************************************/ +traceString prvTraceLookupSymbolTableEntry(const char* name, + uint8_t crc6, + uint8_t len, + traceString chn) +{ + uint16_t i = RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ]; + + TRACE_ASSERT(name != NULL, "prvTraceLookupSymbolTableEntry: name == NULL", (traceString)0); + TRACE_ASSERT(len != 0, "prvTraceLookupSymbolTableEntry: len == 0", (traceString)0); + + while (i != 0) + { + if (RecorderDataPtr->SymbolTable.symbytes[i + 2] == (chn & 0x00FF)) + { + if (RecorderDataPtr->SymbolTable.symbytes[i + 3] == (chn / 0x100)) + { + if (RecorderDataPtr->SymbolTable.symbytes[i + 4 + len] == '\0') + { + if (strncmp((char*)(& RecorderDataPtr->SymbolTable.symbytes[i + 4]), name, len) == 0) + { + break; /* found */ + } + } + } + } + i = (uint16_t)(RecorderDataPtr->SymbolTable.symbytes[i] + (RecorderDataPtr->SymbolTable.symbytes[i + 1] * 0x100)); + } + return i; +} + +/******************************************************************************* + * prvTraceCreateSymbolTableEntry + * + * Creates an entry in the symbol table, independent if it exists already. + * + * The strings are stored in a byte pool, with four bytes of "meta-data" for + * every string. + * byte 0-1: index of next entry with same checksum (for fast lookup). + * byte 2-3: reference to a symbol table entry, a label for vTracePrintF + * format strings only (the handle of the destination channel). + * byte 4..(4 + length): the string (object name or user event label), with + * zero-termination + ******************************************************************************/ +uint16_t prvTraceCreateSymbolTableEntry(const char* name, + uint8_t crc6, + uint8_t len, + traceString channel) +{ + uint16_t ret = 0; + + TRACE_ASSERT(name != NULL, "prvTraceCreateSymbolTableEntry: name == NULL", 0); + TRACE_ASSERT(len != 0, "prvTraceCreateSymbolTableEntry: len == 0", 0); + + if (RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + len + 4 >= TRC_CFG_SYMBOL_TABLE_SIZE) + { + prvTraceError("Symbol table full. Increase TRC_CFG_SYMBOL_TABLE_SIZE in trcConfig.h"); + ret = 0; + } + else + { + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex] = + (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] & 0x00FF); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 1] = + (uint8_t)(RecorderDataPtr->SymbolTable.latestEntryOfChecksum[ crc6 ] / 0x100); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 2] = + (uint8_t)(channel & 0x00FF); + + RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 3] = + (uint8_t)(channel / 0x100); + + /* set name (bytes 4...4+len-1) */ + prvStrncpy((char*)&(RecorderDataPtr->SymbolTable.symbytes + [ RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4]), name, len); + + /* Set zero termination (at offset 4+len) */ + RecorderDataPtr->SymbolTable.symbytes + [RecorderDataPtr->SymbolTable.nextFreeSymbolIndex + 4 + len] = '\0'; + + /* store index of entry (for return value, and as head of LL[crc6]) */ + RecorderDataPtr->SymbolTable.latestEntryOfChecksum + [ crc6 ] = (uint16_t)RecorderDataPtr->SymbolTable.nextFreeSymbolIndex; + + RecorderDataPtr->SymbolTable.nextFreeSymbolIndex += (uint32_t) (len + 5); + + ret = (uint16_t)(RecorderDataPtr->SymbolTable.nextFreeSymbolIndex - (uint8_t)(len + 5)); + } + + return ret; +} + + +/******************************************************************************* + * prvTraceGetChecksum + * + * Calculates a simple 6-bit checksum from a string, used to index the string + * for fast symbol table lookup. + ******************************************************************************/ +void prvTraceGetChecksum(const char *pname, uint8_t* pcrc, uint8_t* plength) +{ + unsigned char c; + int length = 1; /* Should be 1 to account for '\0' */ + int crc = 0; + + TRACE_ASSERT(pname != NULL, "prvTraceGetChecksum: pname == NULL", TRC_UNUSED); + TRACE_ASSERT(pcrc != NULL, "prvTraceGetChecksum: pcrc == NULL", TRC_UNUSED); + TRACE_ASSERT(plength != NULL, "prvTraceGetChecksum: plength == NULL", TRC_UNUSED); + + if (pname != (const char *) 0) + { + for (; (c = (unsigned char) *pname++) != '\0';) + { + crc += c; + length++; + } + } + *pcrc = (uint8_t)(crc & 0x3F); + *plength = (uint8_t)length; +} + +#if (TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1) + +static void prvTraceStoreXID(traceHandle handle); + +/****************************************************************************** + * prvTraceStoreXID + * + * Stores an XID (eXtended IDentifier) event. + * This is used if an object/task handle is larger than 255. + * The parameter "handle" is the full (16 bit) handle, assumed to be 256 or + * larger. Handles below 256 should not use this function. + * + * NOTE: this function MUST be called from within a critical section. + *****************************************************************************/ +static void prvTraceStoreXID(traceHandle handle) +{ + XPSEvent* xid; + + TRACE_ASSERT(handle >= 256, "prvTraceStoreXID: Handle < 256", TRC_UNUSED); + + xid = (XPSEvent*)prvTraceNextFreeEventBufferSlot(); + + if (xid != NULL) + { + xid->type = XID; + + /* This function is (only) used when traceHandle is 16 bit... */ + xid->xps_16 = handle; + + prvTraceUpdateCounters(); + } +} + +static uint8_t prvTraceGet8BitHandle(traceHandle handle) +{ + if (handle > 255) + { + prvTraceStoreXID(handle); + /* The full handle (16 bit) is stored in the XID event. + This code (255) is used instead of zero (which is an error code).*/ + return 255; + } + return (uint8_t)(handle & 0xFF); +} +#endif /*(TRC_CFG_USE_16BIT_OBJECT_HANDLES == 1)*/ + + +/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ +#ifndef TRC_CFG_ARM_CM_USE_SYSTICK +#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) +void prvTraceInitCortexM() +{ + /* Ensure that the DWT registers are unlocked and can be modified. */ + TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; + + /* Make sure DWT is enabled, if supported */ + TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; + + do{ + /* Verify that DWT is supported */ + if (TRC_REG_DEMCR == 0) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + + If the below error is produced, the DWT unit does not seem to be available. + + In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + to use SysTick timestamping instead, or define your own timestamping by + setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError("DWT unit not available, see code comment."); + break; + } + + /* Verify that DWT_CYCCNT is supported */ + if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + + If the below error is produced, the cycle counter does not seem to be available. + + In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + to use SysTick timestamping instead, or define your own timestamping by + setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError("DWT_CYCCNT not available, see code comment."); + break; + } + + /* Reset the cycle counter */ + TRC_REG_DWT_CYCCNT = 0; + + /* Enable the cycle counter */ + TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; + + }while(0); /* breaks above jump here */ +} +#endif +#endif + +/****************************************************************************** + * prvTracePortGetTimeStamp + * + * Returns the current time based on the HWTC macros which provide a hardware + * isolation layer towards the hardware timer/counter. + * + * The HWTC macros and prvTracePortGetTimeStamp is the main porting issue + * or the trace recorder library. Typically you should not need to change + * the code of prvTracePortGetTimeStamp if using the HWTC macros. + * + ******************************************************************************/ +void prvTracePortGetTimeStamp(uint32_t *pTimestamp) +{ + static uint32_t last_hwtc_count = 0; + uint32_t hwtc_count = 0; + +#if TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR + /* systick based timer */ + static uint32_t last_traceTickCount = 0; + uint32_t traceTickCount = 0; +#else /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ + /* Free running timer */ + static uint32_t last_hwtc_rest = 0; + uint32_t diff = 0; + uint32_t diff_scaled = 0; +#endif /*TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR*/ + + if (trace_disable_timestamp == 1) + { + if (pTimestamp) + *pTimestamp = last_timestamp; + return; + } + + /* Retrieve TRC_HWTC_COUNT only once since the same value should be used all throughout this function. */ +#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) + /* Get the increasing tick count */ + hwtc_count = TRC_HWTC_COUNT; +#elif (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR || TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR) + /* Convert decreasing tick count into increasing tick count */ + hwtc_count = TRC_HWTC_PERIOD - TRC_HWTC_COUNT; +#else + #error "TRC_HWTC_TYPE has unexpected value" +#endif + +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_Win32) + /* The Win32 port uses ulGetRunTimeCounterValue for timestamping, which in turn + uses QueryPerformanceCounter. That function is not always reliable when used over + multiple threads. We must therefore handle rare cases where the timestamp is less + than the previous. In practice, this should "never" roll over since the + performance counter is 64 bit wide. */ + + if (last_hwtc_count > hwtc_count) + { + hwtc_count = last_hwtc_count; + } +#endif + +#if (TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR) + /* Timestamping is based on a timer that wraps at TRC_HWTC_PERIOD */ + if (last_traceTickCount - uiTraceTickCount - 1 < 0x80000000) + { + /* This means last_traceTickCount is higher than uiTraceTickCount, + so we have previously compensated for a missed tick. + Therefore we use the last stored value because that is more accurate. */ + traceTickCount = last_traceTickCount; + } + else + { + /* Business as usual */ + traceTickCount = uiTraceTickCount; + } + + /* Check for overflow. May occur if the update of uiTraceTickCount has been + delayed due to disabled interrupts. */ + if (traceTickCount == last_traceTickCount && hwtc_count < last_hwtc_count) + { + /* A trace tick has occurred but not been executed by the kernel, so we compensate manually. */ + traceTickCount++; + } + + /* Check if the return address is OK, then we perform the calculation. */ + if (pTimestamp) + { + /* Get timestamp from trace ticks. Scale down the period to avoid unwanted overflows. */ + last_timestamp = traceTickCount * (TRC_HWTC_PERIOD / TRC_HWTC_DIVISOR); + /* Increase timestamp by (hwtc_count + "lost hardware ticks from scaling down period") / TRC_HWTC_DIVISOR. */ + last_timestamp += (hwtc_count + traceTickCount * (TRC_HWTC_PERIOD % TRC_HWTC_DIVISOR)) / TRC_HWTC_DIVISOR; + } + /* Store the previous value */ + last_traceTickCount = traceTickCount; + +#else /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ + + /* Timestamping is based on a free running timer */ + /* This part handles free running clocks that can be scaled down to avoid too large DTS values. + Without this, the scaled timestamp will incorrectly wrap at (2^32 / TRC_HWTC_DIVISOR) ticks. + The scaled timestamp returned from this function is supposed to go from 0 -> 2^32, which in real time would represent (0 -> 2^32 * TRC_HWTC_DIVISOR) ticks. */ + + /* First we see how long time has passed since the last timestamp call, and we also add the ticks that was lost when we scaled down the last time. */ + diff = (hwtc_count - last_hwtc_count) + last_hwtc_rest; + + /* Scale down the diff */ + diff_scaled = diff / TRC_HWTC_DIVISOR; + + /* Find out how many ticks were lost when scaling down, so we can add them the next time */ + last_hwtc_rest = diff % TRC_HWTC_DIVISOR; + + /* We increase the scaled timestamp by the scaled amount */ + last_timestamp += diff_scaled; +#endif /*(TRC_HWTC_TYPE == TRC_OS_TIMER_INCR || TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)*/ + + /* Is anyone interested in the results? */ + if (pTimestamp) + *pTimestamp = last_timestamp; + + /* Store the previous value */ + last_hwtc_count = hwtc_count; +} + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_SNAPSHOT)*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingConfig.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingConfig.h new file mode 100644 index 0000000..825046e --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingConfig.h @@ -0,0 +1,171 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcStreamingConfig.h + * + * Configuration parameters for the trace recorder library in streaming mode. + * Read more at http://percepio.com/2016/10/05/rtos-tracing/ + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_STREAMING_CONFIG_H +#define TRC_STREAMING_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* + * Configuration Macro: TRC_CFG_SYMBOL_TABLE_SLOTS + * + * The maximum number of symbols names that can be stored. This includes: + * - Task names + * - Named ISRs (vTraceSetISRProperties) + * - Named kernel objects (vTraceStoreKernelObjectName) + * - User event channels (xTraceRegisterString) + * + * If this value is too small, not all symbol names will be stored and the + * trace display will be affected. In that case, there will be warnings + * (as User Events) from TzCtrl task, that monitors this. + ******************************************************************************/ +#define TRC_CFG_SYMBOL_TABLE_SLOTS 30 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_SYMBOL_MAX_LENGTH + * + * The maximum length of symbol names, including: + * - Task names + * - Named ISRs (vTraceSetISRProperties) + * - Named kernel objects (vTraceStoreKernelObjectName) + * - User event channel names (xTraceRegisterString) + * + * If longer symbol names are used, they will be truncated by the recorder, + * which will affect the trace display. In that case, there will be warnings + * (as User Events) from TzCtrl task, that monitors this. + ******************************************************************************/ +#define TRC_CFG_SYMBOL_MAX_LENGTH 24 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_OBJECT_DATA_SLOTS + * + * The maximum number of object data entries (used for task priorities) that can + * be stored at the same time. Must be sufficient for all tasks, otherwise there + * will be warnings (as User Events) from TzCtrl task, that monitors this. + ******************************************************************************/ +#define TRC_CFG_OBJECT_DATA_SLOTS 20 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_STACK_SIZE + * + * The stack size of the TzCtrl task, that receive commands. + * We are aiming to remove this extra task in future versions. + ******************************************************************************/ +#define TRC_CFG_CTRL_TASK_STACK_SIZE 500/sizeof(StackType_t) + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_PRIORITY + * + * The priority of the TzCtrl task, that receive commands from Tracealyzer. + * Most stream ports also rely on the TzCtrl task to transmit the data from the + * internal buffer to the stream interface (all except for the J-Link port). + * For such ports, make sure the TzCtrl priority is high enough to ensure + * reliable periodic execution and transfer of the data. + ******************************************************************************/ +#define TRC_CFG_CTRL_TASK_PRIORITY 1 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_CTRL_TASK_DELAY + * + * The delay between every loop of the TzCtrl task. A high delay will reduce the + * CPU load, but may cause missed events if the TzCtrl task is performing the + * trace transfer. + ******************************************************************************/ +#define TRC_CFG_CTRL_TASK_DELAY ((10 * configTICK_RATE_HZ) / 1000) + +/******************************************************************************* + * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT + * + * Specifies the number of pages used by the paged event buffer. + * This may need to be increased if there are a lot of missed events. + * + * Note: not used by the J-Link RTT stream port (see SEGGER_RTT_Conf.h instead) + ******************************************************************************/ +#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT 2 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE + * + * Specifies the size of each page in the paged event buffer. This can be tuned + * to match any internal low-level buffers used by the streaming interface, like + * the Ethernet MTU (Maximum Transmission Unit). + * + * Note: not used by the J-Link RTT stream port (see SEGGER_RTT_Conf.h instead) + ******************************************************************************/ +#define TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE 2500 + +/******************************************************************************* + * TRC_CFG_ISR_TAILCHAINING_THRESHOLD + * + * Macro which should be defined as an integer value. + * + * If tracing multiple ISRs, this setting allows for accurate display of the + * context-switching also in cases when the ISRs execute in direct sequence. + * + * vTraceStoreISREnd normally assumes that the ISR returns to the previous + * context, i.e., a task or a preempted ISR. But if another traced ISR + * executes in direct sequence, Tracealyzer may incorrectly display a minimal + * fragment of the previous context in between the ISRs. + * + * By using TRC_CFG_ISR_TAILCHAINING_THRESHOLD you can avoid this. This is + * however a threshold value that must be measured for your specific setup. + * See http://percepio.com/2014/03/21/isr_tailchaining_threshold/ + * + * The default setting is 0, meaning "disabled" and that you may get an + * extra fragments of the previous context in between tail-chained ISRs. + * + * Note: This setting has separate definitions in trcSnapshotConfig.h and + * trcStreamingConfig.h, since it is affected by the recorder mode. + ******************************************************************************/ +#define TRC_CFG_ISR_TAILCHAINING_THRESHOLD 0 + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_STREAMING_CONFIG_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.c new file mode 100644 index 0000000..024831f --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.c @@ -0,0 +1,46 @@ + +#include "trcRecorder.h" + +#if (TRC_USE_TRACEALYZER_RECORDER == 1) +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead) +{ + uint32_t bytesRead = 0; + + if (SEGGER_RTT_HASDATA(TRC_CFG_RTT_DOWN_BUFFER_INDEX)) + { + bytesRead = SEGGER_RTT_Read(TRC_CFG_RTT_DOWN_BUFFER_INDEX, (char*)ptrData, size); + + if (ptrBytesRead != NULL) + *ptrBytesRead = (int32_t)bytesRead; + + if (bytesRead != size) + { + return -1; + } + + } + + return 0; +} + +int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten) +{ + uint32_t bytesWritten = SEGGER_RTT_Write(TRC_CFG_RTT_UP_BUFFER_INDEX, (const char*)ptrData, size); + + if (ptrBytesWritten != NULL) + *ptrBytesWritten = (int32_t)bytesWritten; + + if (bytesWritten != size) + { + return -1; + } + + return 0; +} + +#endif +#endif + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.h new file mode 100644 index 0000000..b88d5be --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingPort.h @@ -0,0 +1,195 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcStreamingPort.h + * + * The interface definitions for trace streaming ("stream ports"). + * This "stream port" sets up the recorder to use SEGGER RTT as streaming channel. + * + * Note that this stream port is more complex than the typical case, since + * the J-Link interface uses a separate RAM buffer in SEGGER_RTT.c, instead + * of the default buffer included in the recorder core. The other stream ports + * offer more typical examples of how to define a custom streaming interface. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#ifndef TRC_STREAMING_PORT_H +#define TRC_STREAMING_PORT_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_UP + * + * Defines the size of the "up" RTT buffer (target -> host) to use for writing + * the trace data, for RTT buffer 1 or higher. + * + * This setting is ignored for RTT buffer 0, which can't be reconfigured + * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. + * + * Default buffer size for Tracealyzer is 5000 bytes. + * + * If you have a stand-alone J-Link probe, the can be decreased to around 1 KB. + * But integrated J-Link OB interfaces are slower and needs about 5-10 KB, + * depending on the amount of data produced. + ******************************************************************************/ +#define TRC_CFG_RTT_BUFFER_SIZE_UP 1024 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RTT_BUFFER_SIZE_DOWN + * + * Defines the size of the "down" RTT buffer (host -> target) to use for reading + * commands from Tracealyzer, for RTT buffer 1 or higher. + * + * Default buffer size for Tracealyzer is 32 bytes. + * + * This setting is ignored for RTT buffer 0, which can't be reconfigured + * in runtime and therefore hard-coded to use the defines in SEGGER_RTT_Conf.h. + ******************************************************************************/ +#define TRC_CFG_RTT_BUFFER_SIZE_DOWN 32 + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RTT_UP_BUFFER_INDEX + * + * Defines the RTT buffer to use for writing the trace data. Make sure that + * the PC application has the same setting (File->Settings). + * + * Default: 1 + * + * We don't recommend using RTT buffer 0, since mainly intended for terminals. + * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. + ******************************************************************************/ +#define TRC_CFG_RTT_UP_BUFFER_INDEX 2 /* << EST */ + +/******************************************************************************* + * Configuration Macro: TRC_CFG_RTT_DOWN_BUFFER_INDEX + * + * Defines the RTT buffer to use for reading the trace data. Make sure that + * the PC application has the same setting (File->Settings). + * + * Default: 1 + * + * We don't recommend using RTT buffer 0, since mainly intended for terminals. + * If you prefer to use buffer 0, it must be configured in SEGGER_RTT_Conf.h. + ******************************************************************************/ +#define TRC_CFG_RTT_DOWN_BUFFER_INDEX 2 /* << EST */ +/******************************************************************************* + * TRC_CFG_RTT_MODE + * This stream port for J-Link streaming relies on SEGGER RTT, that contains an + * internal RAM buffer read by the J-Link probes during execution. + * + * Possible values: + * - SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (default) + * - SEGGER_RTT_MODE_NO_BLOCK_SKIP + * + * We recommend using SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL, to ensure you get a + * complete and valid trace. This may however cause blocking if your streaming + * interface isn't fast enough, which may disturb the real-time behavior. + * We therefore recommend to try SEGGER_RTT_MODE_NO_BLOCK_SKIP as well. + * In this mode, Tracealyzer will report lost events if the transfer is not + * fast enough. In that case, try increasing the size of the "up buffer". + ******************************************************************************/ +#define TRC_CFG_RTT_MODE SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL + +#include "SEGGER_RTT_Conf.h" +#include "SEGGER_RTT.h" + +#if (TRC_CFG_RTT_UP_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_UP_BUFFERS) +#error "TRC_CFG_RTT_UP_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_UP_BUFFERS" +#endif + +#if (TRC_CFG_RTT_DOWN_BUFFER_INDEX >= SEGGER_RTT_MAX_NUM_DOWN_BUFFERS) +#error "TRC_CFG_RTT_DOWN_BUFFER_INDEX must be smaller than SEGGER_RTT_MAX_NUM_DOWN_BUFFERS" +#endif + +/* If index is defined as 0, the internal RTT buffers will be used instead of this. */ +#if TRC_CFG_RTT_UP_BUFFER_INDEX == 0 +#define TRC_RTT_ALLOC_UP() static char* _TzTraceData = NULL; /* Not actually used. Ignore allocation method. */ +#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ +#else +#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_STATIC +#define TRC_RTT_ALLOC_UP() char _TzTraceData[TRC_CFG_RTT_BUFFER_SIZE_UP]; /* Static allocation */ +#define TRC_STREAM_PORT_MALLOC() /* Static allocation. Not used. */ +#endif +#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_DYNAMIC +#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Dynamic allocation */ +#define TRC_STREAM_PORT_MALLOC() _TzTraceData = TRC_PORT_MALLOC(TRC_CFG_RTT_BUFFER_SIZE_UP); +#endif +#if TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM +#define TRC_RTT_ALLOC_UP() char* _TzTraceData = NULL; /* Custom allocation, user needs to call vTraceSetRecorderDataBuffer before vTraceEnable, to assign this */ +#define TRC_STREAM_PORT_MALLOC() /* Not used in custom mode */ +#endif +#endif + +/* Down-buffer. If index is defined as 0, the internal RTT buffers will be used instead of this. */ \ +#if TRC_CFG_RTT_DOWN_BUFFER_INDEX == 0 +#define TRC_RTT_ALLOC_DOWN() static char* _TzCtrlData = NULL; /* Not actually used. Ignore allocation method. */ +#else +#define TRC_RTT_ALLOC_DOWN() static char _TzCtrlData[TRC_CFG_RTT_BUFFER_SIZE_DOWN]; /* Always static allocation, since usually small. */ +#endif + +#define TRC_STREAM_PORT_ALLOCATE_FIELDS() \ + TRC_RTT_ALLOC_UP() /* Macro that will result in proper UP buffer allocation */ \ + TRC_RTT_ALLOC_DOWN() /* Macro that will result in proper DOWN buffer allocation */ + +int32_t readFromRTT(void* ptrData, uint32_t size, int32_t* ptrBytesRead); + +int32_t writeToRTT(void* ptrData, uint32_t size, int32_t* ptrBytesWritten); + + +#define TRC_STREAM_PORT_INIT() \ + TRC_STREAM_PORT_MALLOC(); /*Dynamic allocation or empty if static */ \ + SEGGER_RTT_ConfigUpBuffer(TRC_CFG_RTT_UP_BUFFER_INDEX, "TzData", _TzTraceData, TRC_CFG_RTT_BUFFER_SIZE_UP, TRC_CFG_RTT_MODE ); \ + SEGGER_RTT_ConfigDownBuffer(TRC_CFG_RTT_DOWN_BUFFER_INDEX, "TzCtrl", _TzCtrlData, TRC_CFG_RTT_BUFFER_SIZE_DOWN, TRC_CFG_RTT_MODE); + +/* Important for the J-Link port, in most other ports this can be skipped (default is 1) */ +#define TRC_STREAM_PORT_USE_INTERNAL_BUFFER 0 + +#define TRC_STREAM_PORT_WRITE_DATA(_ptrData, _size, _ptrBytesWritten) writeToRTT(_ptrData, _size, _ptrBytesWritten) + +#define TRC_STREAM_PORT_READ_DATA(_ptrData, _size, _ptrBytesRead) readFromRTT(_ptrData, _size, _ptrBytesRead) + +#ifdef __cplusplus +} +#endif + +#endif /* TRC_STREAMING_PORT_H */ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingRecorder.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingRecorder.c new file mode 100644 index 0000000..9274555 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/trcStreamingRecorder.c @@ -0,0 +1,1867 @@ +/******************************************************************************* + * Trace Recorder Library for Tracealyzer v3.3.0 + * Percepio AB, www.percepio.com + * + * trcStreamingRecorder.c + * + * The generic core of the trace recorder's streaming mode. + * + * Terms of Use + * This file is part of the trace recorder library (RECORDER), which is the + * intellectual property of Percepio AB (PERCEPIO) and provided under a + * license as follows. + * The RECORDER may be used free of charge for the purpose of recording data + * intended for analysis in PERCEPIO products. It may not be used or modified + * for other purposes without explicit permission from PERCEPIO. + * You may distribute the RECORDER in its original source code form, assuming + * this text (terms of use, disclaimer, copyright notice) is unchanged. You are + * allowed to distribute the RECORDER with minor modifications intended for + * configuration or porting of the RECORDER, e.g., to allow using it on a + * specific processor, processor family or with a specific communication + * interface. Any such modifications should be documented directly below + * this comment block. + * + * Disclaimer + * The RECORDER is being delivered to you AS IS and PERCEPIO makes no warranty + * as to its use or performance. PERCEPIO does not and cannot warrant the + * performance or results you may obtain by using the RECORDER or documentation. + * PERCEPIO make no warranties, express or implied, as to noninfringement of + * third party rights, merchantability, or fitness for any particular purpose. + * In no event will PERCEPIO, its technology partners, or distributors be liable + * to you for any consequential, incidental or special damages, including any + * lost profits or lost savings, even if a representative of PERCEPIO has been + * advised of the possibility of such damages, or for any claim by any third + * party. Some jurisdictions do not allow the exclusion or limitation of + * incidental, consequential or special damages, or the exclusion of implied + * warranties or limitations on how long an implied warranty may last, so the + * above limitations may not apply to you. + * + * Tabs are used for indent in this file (1 tab = 4 spaces) + * + * Copyright Percepio AB, 2017. + * www.percepio.com + ******************************************************************************/ + +#include "trcRecorder.h" + +#if (TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING) + +#if (TRC_USE_TRACEALYZER_RECORDER == 1) + +typedef struct{ + uint16_t EventID; + uint16_t EventCount; + uint32_t TS; +} BaseEvent; + +typedef struct{ + BaseEvent base; + uint32_t param1; +} EventWithParam_1; + +typedef struct{ + BaseEvent base; + uint32_t param1; + uint32_t param2; +} EventWithParam_2; + +typedef struct{ + BaseEvent base; + uint32_t param1; + uint32_t param2; + uint32_t param3; +} EventWithParam_3; + +/* Used in event functions with variable number of parameters. */ +typedef struct +{ + BaseEvent base; + uint32_t data[15]; /* maximum payload size */ +} largestEventType; + +typedef struct{ + uint32_t psf; + uint16_t version; + uint16_t platform; + uint32_t options; + uint16_t symbolSize; + uint16_t symbolCount; + uint16_t objectDataSize; + uint16_t objectDataCount; +} PSFHeaderInfo; + + +/* The size of each slot in the Symbol Table */ +#define SYMBOL_TABLE_SLOT_SIZE (sizeof(uint32_t) + (((TRC_CFG_SYMBOL_MAX_LENGTH)+(sizeof(uint32_t)-1))/sizeof(uint32_t))*sizeof(uint32_t)) + +#define OBJECT_DATA_SLOT_SIZE (sizeof(uint32_t) + sizeof(uint32_t)) + +/* The total size of the Symbol Table */ +#define SYMBOL_TABLE_BUFFER_SIZE ((TRC_CFG_SYMBOL_TABLE_SLOTS) * SYMBOL_TABLE_SLOT_SIZE) + +/* The total size of the Object Data Table */ +#define OBJECT_DATA_TABLE_BUFFER_SIZE ((TRC_CFG_OBJECT_DATA_SLOTS) * OBJECT_DATA_SLOT_SIZE) + +/* The Symbol Table type - just a byte array */ +typedef struct{ + union + { + uint32_t pSymbolTableBufferUINT32[SYMBOL_TABLE_BUFFER_SIZE / sizeof(uint32_t)]; + uint8_t pSymbolTableBufferUINT8[SYMBOL_TABLE_BUFFER_SIZE]; + } SymbolTableBuffer; +} SymbolTable; + +/* The Object Data Table type - just a byte array */ +typedef struct{ + union + { + uint32_t pObjectDataTableBufferUINT32[OBJECT_DATA_TABLE_BUFFER_SIZE / sizeof(uint32_t)]; + uint8_t pObjectDataTableBufferUINT8[OBJECT_DATA_TABLE_BUFFER_SIZE]; + } ObjectDataTableBuffer; +} ObjectDataTable; + +typedef struct{ + uint16_t Status; /* 16 bit to avoid implicit padding (warnings) */ + uint16_t BytesRemaining; + char* WritePointer; +} PageType; + +/* Code used for "task address" when no task has started. (NULL = idle task) */ +#define HANDLE_NO_TASK 2 + +#define PAGE_STATUS_FREE 0 +#define PAGE_STATUS_WRITE 1 +#define PAGE_STATUS_READ 2 + +#define PSF_ASSERT(_assert, _err) if (! (_assert)){ prvTraceError(_err); return; } + +/* Part of the PSF format - encodes the number of 32-bit params in an event */ +#define PARAM_COUNT(n) ((n & 0xF) << 12) + +/* The Symbol Table instance - keeps names of tasks and other named objects. */ +static SymbolTable symbolTable = { { { 0 } } }; + +/* This points to the first unused entry in the symbol table. */ +static uint32_t firstFreeSymbolTableIndex = 0; + +/* The Object Data Table instance - keeps initial priorities of tasks. */ +static ObjectDataTable objectDataTable = { { { 0 } } }; + +/* This points to the first unused entry in the object data table. */ +static uint32_t firstFreeObjectDataTableIndex = 0; + +/* Keeps track of ISR nesting */ +static uint32_t ISR_stack[TRC_CFG_MAX_ISR_NESTING]; + +/* Keeps track of ISR nesting */ +static int8_t ISR_stack_index = -1; + +/* Any error that occurred in the recorder (also creates User Event) */ +static int errorCode = 0; + +/* Counts the number of trace sessions (not yet used) */ +static uint32_t SessionCounter = 0u; + +/* Master switch for recording (0 => Disabled, 1 => Enabled) */ +uint32_t RecorderEnabled = 0u; + +/* Used to determine endian of data (big/little) */ +static uint32_t PSFEndianessIdentifier = 0x50534600; + +/* Used to interpret the data format */ +static uint16_t FormatVersion = 0x0004; + +/* The number of events stored. Used as event sequence number. */ +static uint32_t eventCounter = 0; + +/* The user event channel for recorder warnings, defined in trcKernelPort.c */ +extern char* trcWarningChannel; + +/* Remembers if an earlier ISR in a sequence of adjacent ISRs has triggered a task switch. +In that case, vTraceStoreISREnd does not store a return to the previously executing task. */ +int32_t isPendingContextSwitch = 0; + +uint32_t uiTraceTickCount = 0; +uint32_t timestampFrequency = 0; +uint32_t DroppedEventCounter = 0; +uint32_t TotalBytesRemaining_LowWaterMark = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; +uint32_t TotalBytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; + +PageType PageInfo[TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT]; + +char* EventBuffer = NULL; + +/******************************************************************************* + * NoRoomForSymbol + * + * Incremented on prvTraceSaveSymbol if no room for saving the symbol name. This + * is used for storing the names of: + * - Tasks + * - Named ISRs (xTraceSetISRProperties) + * - Named kernel objects (vTraceStoreKernelObjectName) + * - User event channels (xTraceRegisterString) + * + * This variable should be zero. If not, it shows the number of missing slots so + * far. In that case, increment SYMBOL_TABLE_SLOTS with (at least) this value. + ******************************************************************************/ +volatile uint32_t NoRoomForSymbol = 0; + +/******************************************************************************* + * NoRoomForObjectData + * + * Incremented on prvTraceSaveObjectData if no room for saving the object data, + * i.e., the base priorities of tasks. There must be one slot for each task. + * If not, this variable will show the difference. + * + * This variable should be zero. If not, it shows the number of missing slots so + * far. In that case, increment OBJECT_DATA_SLOTS with (at least) this value. + ******************************************************************************/ +volatile uint32_t NoRoomForObjectData = 0; + +/******************************************************************************* + * LongestSymbolName + * + * Updated in prvTraceSaveSymbol. Should not exceed TRC_CFG_SYMBOL_MAX_LENGTH, + * otherwise symbol names will be truncated. In that case, set + * TRC_CFG_SYMBOL_MAX_LENGTH to (at least) this value. + ******************************************************************************/ +volatile uint32_t LongestSymbolName = 0; + +/******************************************************************************* + * MaxBytesTruncated + * + * Set in prvTraceStoreStringEvent if the total data payload exceeds 60 bytes, + * including data arguments and the string. For user events, that is 52 bytes + * for string and data arguments. In that is exceeded, the event is truncated + * (usually only the string, unless more than 15 parameters) and this variable + * holds the maximum number of truncated bytes, from any event. + ******************************************************************************/ +volatile uint32_t MaxBytesTruncated = 0; + +uint16_t CurrentFilterMask = 0xFFFF; + +uint16_t CurrentFilterGroup = FilterGroup0; + +/* Internal common function for storing string events */ +static void prvTraceStoreStringEventHelper( int nArgs, + uint16_t eventID, + traceString userEvtChannel, + const char* str, + va_list* vl); + +/* Not static to avoid warnings from SysGCC/PPC */ +void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel, + const char* str); + + +/* Stores the header information on Start */ +static void prvTraceStoreHeader(void); + +/* Stores the symbol table on Start */ +static void prvTraceStoreSymbolTable(void); + +/* Stores the object table on Start */ +static void prvTraceStoreObjectDataTable(void); + +/* Store the Timestamp Config on Start */ +static void prvTraceStoreTSConfig(void); + +/* Store the current warnings */ +static void prvTraceStoreWarnings(void); + +/* Internal function for starting/stopping the recorder. */ +static void prvSetRecorderEnabled(uint32_t isEnabled); + +/* Mark the page read as complete. */ +static void prvPageReadComplete(int pageIndex); + +/* Retrieve a buffer page to write to. */ +static int prvAllocateBufferPage(int prevPage); + +/* Get the current buffer page index (return value) and the number +of valid bytes in the buffer page (bytesUsed). */ +static int prvGetBufferPage(int32_t* bytesUsed); + +/* Performs timestamping using definitions in trcHardwarePort.h */ +static uint32_t prvGetTimestamp32(void); + +/* Signal an error. */ +void prvTraceError(int errCode); + +/* Signal an warning (does not stop the recorder). */ +void prvTraceWarning(int errCode); + +/****************************************************************************** + * vTraceInstanceFinishedNow + * + * Creates an event that ends the current task instance at this very instant. + * This makes the viewer to splits the current fragment at this point and begin + * a new actor instance, even if no task-switch has occurred. + *****************************************************************************/ +void vTraceInstanceFinishedNow(void) +{ + prvTraceStoreEvent0(PSF_EVENT_IFE_DIRECT); +} + +/****************************************************************************** + * vTraceInstanceFinishedNext + * + * Marks the current "task instance" as finished on the next kernel call. + * + * If that kernel call is blocking, the instance ends after the blocking event + * and the corresponding return event is then the start of the next instance. + * If the kernel call is not blocking, the viewer instead splits the current + * fragment right before the kernel call, which makes this call the first event + * of the next instance. + *****************************************************************************/ +void vTraceInstanceFinishedNext(void) +{ + prvTraceStoreEvent0(PSF_EVENT_IFE_NEXT); +} + +/******************************************************************************* + * vTraceStoreKernelObjectName + * + * Parameter object: pointer to the Event Group that shall be named + * Parameter name: the name to set (const string literal) + * + * Sets a name for a kernel object for display in Tracealyzer. + ******************************************************************************/ +void vTraceStoreKernelObjectName(void* object, const char* name) +{ + /* Always save in symbol table, if the recording has not yet started */ + prvTraceSaveSymbol(object, name); + + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, name, (uint32_t)object); +} + + +/****************************************************************************** +* vTraceSetFrequency +* +* Registers the clock rate of the time source for the event timestamping. +* This is normally not required, but if the default value (TRC_HWTC_FREQ_HZ) +* should be incorrect for your setup, you can override it using this function. +* +* Must be called prior to vTraceEnable, and the time source is assumed to +* have a fixed clock frequency after the startup. +*****************************************************************************/ +void vTraceSetFrequency(uint32_t frequency) +{ + timestampFrequency = frequency; +} + +#if (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) + +/******************************************************************************* +* xTraceRegisterString +* +* Stores a name for a user event channel, returns the handle. +******************************************************************************/ +traceString xTraceRegisterString(const char* name) +{ + prvTraceSaveSymbol((const void*)name, name); + + /* Always save in symbol table, if the recording has not yet started */ + prvTraceStoreStringEvent(1, PSF_EVENT_OBJ_NAME, (const char*)name, (uint32_t)name); + + return (traceString)name; +} + +/****************************************************************************** + * vTracePrint + * + * Generates "User Events", with unformatted text. + * + * User Events can be used for very efficient application logging, and are shown + * as yellow labels in the main trace view. + * + * You may group User Events into User Event Channels. The yellow User Event + * labels shows the logged string, preceded by the channel name within + * brackets. For example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceRegisterString(). + * + * Example: + * + * traceString chn = xTraceRegisterString("MyChannel"); + * ... + * vTracePrint(chn, "Hello World!"); + * + ******************************************************************************/ +void vTracePrint(traceString chn, const char* str) +{ + prvTraceStoreSimpleStringEventHelper(chn, str); +} + +/****************************************************************************** + * vTracePrintF + * + * Generates "User Events", with formatted text and data, similar to a "printf". + * It is very fast since the actual formatting is done on the host side when the + * trace is displayed. + * + * User Events can be used for very efficient application logging, and are shown + * as yellow labels in the main trace view. + * An advantage of User Events is that data can be plotted in the "User Event + * Signal Plot" view, visualizing any data you log as User Events, discrete + * states or control system signals (e.g. system inputs or outputs). + * + * You may group User Events into User Event Channels. The yellow User Event + * labels show the logged string, preceded by the channel name within brackets. + * + * Example: + * + * "[MyChannel] Hello World!" + * + * The User Event Channels are shown in the View Filter, which makes it easy to + * select what User Events you wish to display. User Event Channels are created + * using xTraceRegisterString(). + * + * Example: + * + * traceString adc_uechannel = xTraceRegisterString("ADC User Events"); + * ... + * vTracePrintF(adc_uechannel, + * "ADC channel %d: %d volts", + * ch, adc_reading); + * + * All data arguments are assumed to be 32 bit wide. The following formats are + * supported: + * %d - signed integer. The following width and padding format is supported: "%05d" -> "-0042" and "%5d" -> " -42" + * %u - unsigned integer. The following width and padding format is supported: "%05u" -> "00042" and "%5u" -> " 42" + * %X - hexadecimal (uppercase). The following width and padding format is supported: "%04X" -> "002A" and "%4X" -> " 2A" + * %x - hexadecimal (lowercase). The following width and padding format is supported: "%04x" -> "002a" and "%4x" -> " 2a" + * %s - string (currently, this must be an earlier stored symbol name) + * + * Up to 15 data arguments are allowed, with a total size of maximum 60 byte + * including 8 byte for the base event fields and the format string. So with + * one data argument, the maximum string length is 48 chars. If this is exceeded + * the string is truncated (4 bytes at a time). + * + ******************************************************************************/ +void vTracePrintF(traceString chn, const char* fmt, ...) +{ + va_list vl; + int i = 0; + + int nArgs = 0; + + /* Count the number of arguments in the format string (e.g., %d) */ + for (i = 0; (fmt[i] != 0) && (i < 52); i++) + { + if (fmt[i] == '%') + { + if (fmt[i + 1] != '%') + { + nArgs++; /* Found an argument */ + } + + i++; /* Move past format specifier or non-argument '%' */ + } + } + + va_start(vl, fmt); + + if (chn != NULL) + { + prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs + 1), chn, fmt, &vl); + } + else + { + prvTraceStoreStringEventHelper(nArgs, (uint16_t)(PSF_EVENT_USER_EVENT + nArgs), chn, fmt, &vl); + } + va_end(vl); +} +#endif /* (TRC_CFG_SCHEDULING_ONLY == 0) && (TRC_CFG_INCLUDE_USER_EVENTS == 1) */ + +/******************************************************************************* + * xTraceSetISRProperties + * + * Stores a name and priority level for an Interrupt Service Routine, to allow + * for better visualization. Returns a traceHandle used by vTraceStoreISRBegin. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + * + ******************************************************************************/ +traceHandle xTraceSetISRProperties(const char* name, uint8_t priority) +{ + /* Save object data in object data table */ + prvTraceSaveObjectData((const void*)name, priority); + + /* Note: "name" is used both as a string argument, and the address as ID */ + prvTraceStoreStringEvent(2, PSF_EVENT_DEFINE_ISR, name, name, priority); + + /* Always save in symbol table, if the recording has not yet started */ + prvTraceSaveSymbol((const void*)name, name); + + return (traceHandle)name; +} + +/******************************************************************************* + * vTraceStoreISRBegin + * + * Registers the beginning of an Interrupt Service Routine, using a traceHandle + * provided by xTraceSetISRProperties. + * + * Example: + * #define PRIO_ISR_TIMER1 3 // the hardware priority of the interrupt + * ... + * traceHandle Timer1Handle = xTraceSetISRProperties("ISRTimer1", PRIO_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(Timer1Handle); + * ... + * vTraceStoreISREnd(0); + * } + * + ******************************************************************************/ +void vTraceStoreISRBegin(traceHandle handle) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + /* We are at the start of a possible ISR chain. + No context switches should have been triggered now. */ + if (ISR_stack_index == -1) + isPendingContextSwitch = 0; + + if (ISR_stack_index < TRC_CFG_MAX_ISR_NESTING - 1) + { + ISR_stack_index++; + ISR_stack[ISR_stack_index] = (uint32_t)handle; +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) + prvTraceStoreEvent1(PSF_EVENT_ISR_BEGIN, (uint32_t)handle); +#endif + TRACE_EXIT_CRITICAL_SECTION(); + } + else + { + TRACE_EXIT_CRITICAL_SECTION(); + prvTraceError(PSF_ERROR_ISR_NESTING_OVERFLOW); + } +} + +/******************************************************************************* + * vTraceStoreISREnd + * + * Registers the end of an Interrupt Service Routine. + * + * The parameter pendingISR indicates if the interrupt has requested a + * task-switch (= 1), e.g., by signaling a semaphore. Otherwise (= 0) the + * interrupt is assumed to return to the previous context. + * + * Example: + * #define PRIO_OF_ISR_TIMER1 3 // the hardware priority of the interrupt + * traceHandle traceHandleIsrTimer1 = 0; // The ID set by the recorder + * ... + * traceHandleIsrTimer1 = xTraceSetISRProperties("ISRTimer1", PRIO_OF_ISR_TIMER1); + * ... + * void ISR_handler() + * { + * vTraceStoreISRBegin(traceHandleIsrTimer1); + * ... + * vTraceStoreISREnd(0); + * } + * + ******************************************************************************/ +void vTraceStoreISREnd(int isTaskSwitchRequired) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + /* Is there a pending task-switch? (perhaps from an earlier ISR) */ + isPendingContextSwitch |= isTaskSwitchRequired; + + if (ISR_stack_index > 0) + { + ISR_stack_index--; + +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) + /* Store return to interrupted ISR (if nested ISRs)*/ + prvTraceStoreEvent1(PSF_EVENT_ISR_RESUME, (uint32_t)ISR_stack[ISR_stack_index]); +#endif + } + else + { + ISR_stack_index--; + + /* Store return to interrupted task, if no context switch will occur in between. */ + if ((isPendingContextSwitch == 0) || (prvTraceIsSchedulerSuspended())) + { +#if (TRC_CFG_INCLUDE_ISR_TRACING == 1) +#if 1 /* << EST: avoid gcc warning "cast from function call of type 'void *' to non-matching type 'long unsigned int' [-Wbad-function-cast]" */ + void *t; + t = TRACE_GET_CURRENT_TASK(); + + prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)t); +#else + prvTraceStoreEvent1(PSF_EVENT_TS_RESUME, (uint32_t)TRACE_GET_CURRENT_TASK()); +#endif +#endif + } + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + + +/******************************************************************************* + * xTraceGetLastError + * + * Returns the last error or warning, as a string, or NULL if none. + *****************************************************************************/ +const char* xTraceGetLastError(void) +{ + /* Note: the error messages are short, in order to fit in a User Event. + Instead, the users can read more in the below comments.*/ + + switch (errorCode) + { + + case PSF_WARNING_SYMBOL_TABLE_SLOTS: + /* There was not enough symbol table slots for storing symbol names. + The number of missing slots is counted by NoRoomForSymbol. Inspect this + variable and increase TRC_CFG_SYMBOL_TABLE_SLOTS by at least that value. */ + + return "Exceeded SYMBOL_TABLE_SLOTS (see xTraceGetLastError)"; + + case PSF_WARNING_SYMBOL_MAX_LENGTH: + /* A symbol name exceeded TRC_CFG_SYMBOL_MAX_LENGTH in length. + Make sure the symbol names are at most TRC_CFG_SYMBOL_MAX_LENGTH, + or inspect LongestSymbolName and increase TRC_CFG_SYMBOL_MAX_LENGTH + to at least this value. */ + + return "Exceeded SYMBOL_MAX_LENGTH (see xTraceGetLastError)"; + + case PSF_WARNING_OBJECT_DATA_SLOTS: + /* There was not enough symbol object table slots for storing object + properties, such as task priorites. The number of missing slots is + counted by NoRoomForObjectData. Inspect this variable and increase + TRC_CFG_OBJECT_DATA_SLOTS by at least that value. */ + + return "Exceeded OBJECT_DATA_SLOTS (see xTraceGetLastError)"; + + case PSF_WARNING_STRING_TOO_LONG: + /* Some string argument was longer than the maximum payload size + and has been truncated by "MaxBytesTruncated" bytes. + + This may happen for the following functions: + - vTracePrint + - vTracePrintF + - vTraceStoreKernelObjectName + - xTraceRegisterString + - vTraceSetISRProperties + + A PSF event may store maximum 60 bytes payload, including data + arguments and string characters. For User Events, also the User + Event Channel (4 bytes) must be squeezed in, if a channel is + specified (can be NULL). */ + + return "String too long (see xTraceGetLastError)"; + + case PSF_WARNING_STREAM_PORT_READ: + /* TRC_STREAM_PORT_READ_DATA is expected to return 0 when completed successfully. + This means there is an error in the communication with host/Tracealyzer. */ + + return "TRC_STREAM_PORT_READ_DATA returned error (!= 0)."; + + case PSF_WARNING_STREAM_PORT_WRITE: + /* TRC_STREAM_PORT_WRITE_DATA is expected to return 0 when completed successfully. + This means there is an error in the communication with host/Tracealyzer. */ + + return "TRC_STREAM_PORT_WRITE_DATA returned error (!= 0)."; + + case PSF_ERROR_EVENT_CODE_TOO_LARGE: + /* The highest allowed event code is 4095, anything higher is an unexpected error. + Please contact support@percepio.com for assistance.*/ + + return "Invalid event code (see xTraceGetLastError)"; + + case PSF_ERROR_ISR_NESTING_OVERFLOW: + /* Nesting of ISR trace calls exceeded the limit (TRC_CFG_MAX_ISR_NESTING). + If this is unlikely, make sure that you call vTraceStoreISRExit in the end + of all ISR handlers. Or increase TRC_CFG_MAX_ISR_NESTING. */ + + return "Exceeded ISR nesting (see xTraceGetLastError)"; + + case PSF_ERROR_DWT_NOT_SUPPORTED: + /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. + DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M + macro normally set by ARM's CMSIS library, since typically available. You can however select + SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ + + return "DWT not supported (see xTraceGetLastError)"; + + case PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED: + /* On ARM Cortex-M only - failed to initialize DWT Cycle Counter since not supported by this chip. + DWT timestamping is selected automatically for ART Cortex-M3, M4 and higher, based on the __CORTEX_M + macro normally set by ARM's CMSIS library, since typically available. You can however select + SysTick timestamping instead by defining adding "#define TRC_CFG_ARM_CM_USE_SYSTICK".*/ + + return "DWT_CYCCNT not supported (see xTraceGetLastError)"; + + case PSF_ERROR_TZCTRLTASK_NOT_CREATED: + /* vTraceEnable failed creating the trace control task (TzCtrl) - incorrect parameters (priority?) + or insufficient heap size? */ + return "Could not create TzCtrl (see xTraceGetLastError)"; + + } + + return NULL; +} + +/******************************************************************************* + * vTraceClearError + * + * Clears any errors. + *****************************************************************************/ +void vTraceClearError(void) +{ + NoRoomForSymbol = 0; + LongestSymbolName = 0; + NoRoomForObjectData = 0; + MaxBytesTruncated = 0; + errorCode = PSF_ERROR_NONE; +} + +/******************************************************************************* + * vTraceStop + * + * Stops the tracing. + *****************************************************************************/ +void vTraceStop(void) +{ + prvSetRecorderEnabled(0); +} + +/******************************************************************************* + * vTraceSetRecorderDataBuffer + * + * If custom allocation is used, this function must be called so the recorder + * library knows where to save the trace data. + ******************************************************************************/ +#if (TRC_CFG_RECORDER_BUFFER_ALLOCATION == TRC_RECORDER_BUFFER_ALLOCATION_CUSTOM) + +extern char* _TzTraceData; + +void vTraceSetRecorderDataBuffer(void* pRecorderData) +{ + _TzTraceData = pRecorderData; +} +#endif + + +/******************************************************************************* +* xTraceIsRecordingEnabled +* Returns true (1) if the recorder is enabled (i.e. is recording), otherwise 0. +******************************************************************************/ +int xTraceIsRecordingEnabled(void) +{ + return (int)RecorderEnabled; +} + +void vTraceSetFilterMask(uint16_t filterMask) +{ + CurrentFilterMask = filterMask; +} + +void vTraceSetFilterGroup(uint16_t filterGroup) +{ + CurrentFilterGroup = filterGroup; +} + + +/******************************************************************************/ +/*** INTERNAL FUNCTIONS *******************************************************/ +/******************************************************************************/ + +/* Internal function for starting/stopping the recorder. */ +static void prvSetRecorderEnabled(uint32_t isEnabled) +{ + void* currentTask; + + TRACE_ALLOC_CRITICAL_SECTION(); + + currentTask = TRACE_GET_CURRENT_TASK(); + + TRACE_ENTER_CRITICAL_SECTION(); + + RecorderEnabled = isEnabled; + + if (currentTask == NULL) + { + currentTask = (void*)HANDLE_NO_TASK; + } + + if (RecorderEnabled) + { + TRC_STREAM_PORT_ON_TRACE_BEGIN(); + + #if (TRC_STREAM_PORT_USE_INTERNAL_BUFFER == 1) + prvPagedEventBufferInit(_TzTraceData); + #endif + + eventCounter = 0; + ISR_stack_index = -1; + prvTraceStoreHeader(); + prvTraceStoreSymbolTable(); + prvTraceStoreObjectDataTable(); + prvTraceStoreEvent3( PSF_EVENT_TRACE_START, + (uint32_t)TRACE_GET_OS_TICKS(), + (uint32_t)currentTask, + SessionCounter++); + prvTraceStoreTSConfig(); + prvTraceStoreWarnings(); + } + else + { + TRC_STREAM_PORT_ON_TRACE_END(); + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Stores the symbol table on Start */ +static void prvTraceStoreSymbolTable(void) +{ + uint32_t i = 0; + uint32_t j = 0; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + for (i = 0; i < (sizeof(SymbolTable) / sizeof(uint32_t)); i += (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t))) + { + TRC_STREAM_PORT_ALLOCATE_EVENT(uint32_t, data, SYMBOL_TABLE_SLOT_SIZE); + if (data != NULL) + { + for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE / sizeof(uint32_t)); j++) + { + data[j] = symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i+j]; + } + TRC_STREAM_PORT_COMMIT_EVENT(data, SYMBOL_TABLE_SLOT_SIZE); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Stores the object table on Start */ +static void prvTraceStoreObjectDataTable(void) +{ + uint32_t i = 0; + uint32_t j = 0; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + for (i = 0; i < (sizeof(ObjectDataTable) / sizeof(uint32_t)); i += (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t))) + { + TRC_STREAM_PORT_ALLOCATE_EVENT(uint32_t, data, OBJECT_DATA_SLOT_SIZE); + if (data != NULL) + { + for (j = 0; j < (OBJECT_DATA_SLOT_SIZE / sizeof(uint32_t)); j++) + { + data[j] = objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i+j]; + } + TRC_STREAM_PORT_COMMIT_EVENT(data, OBJECT_DATA_SLOT_SIZE); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Stores the header information on Start */ +static void prvTraceStoreHeader(void) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + TRC_STREAM_PORT_ALLOCATE_EVENT(PSFHeaderInfo, header, sizeof(PSFHeaderInfo)); + if (header != NULL) + { + header->psf = PSFEndianessIdentifier; + header->version = FormatVersion; + header->platform = TRACE_KERNEL_VERSION; + header->options = 0; + /* Lowest bit used for TRC_IRQ_PRIORITY_ORDER */ + header->options = header->options | (TRC_IRQ_PRIORITY_ORDER << 0); + header->symbolSize = SYMBOL_TABLE_SLOT_SIZE; + header->symbolCount = (TRC_CFG_SYMBOL_TABLE_SLOTS); + header->objectDataSize = 8; + header->objectDataCount = TRC_CFG_OBJECT_DATA_SLOTS; + TRC_STREAM_PORT_COMMIT_EVENT(header, sizeof(PSFHeaderInfo)); + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Store the current warnings */ +static void prvTraceStoreWarnings(void) +{ + if (RecorderEnabled) + { + const char* errStr = xTraceGetLastError(); + + if (errStr != NULL) + { +#if TRC_CFG_INCLUDE_USER_EVENTS /* << EST only available if TRC_CFG_INCLUDE_USER_EVENTS is turned on */ + vTracePrint(trcWarningChannel, errStr); +#endif + } + } +} + +/* Store an event with zero parameters (event ID only) */ +void prvTraceStoreEvent0(uint16_t eventID) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_EVENT(BaseEvent, event, sizeof(BaseEvent)); + if (event != NULL) + { + event->EventID = eventID | PARAM_COUNT(0); + event->EventCount = (uint16_t)eventCounter; + event->TS = prvGetTimestamp32(); + TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(BaseEvent)); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Store an event with one 32-bit parameter (pointer address or an int) */ +void prvTraceStoreEvent1(uint16_t eventID, uint32_t param1) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_1, event, sizeof(EventWithParam_1)); + if (event != NULL) + { + event->base.EventID = eventID | PARAM_COUNT(1); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + event->param1 = (uint32_t)param1; + TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_1)); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Store an event with two 32-bit parameters */ +void prvTraceStoreEvent2(uint16_t eventID, uint32_t param1, uint32_t param2) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_2, event, sizeof(EventWithParam_2)); + if (event != NULL) + { + event->base.EventID = eventID | PARAM_COUNT(2); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + event->param1 = (uint32_t)param1; + event->param2 = param2; + TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_2)); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Store an event with three 32-bit parameters */ +void prvTraceStoreEvent3( uint16_t eventID, + uint32_t param1, + uint32_t param2, + uint32_t param3) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_EVENT(EventWithParam_3, event, sizeof(EventWithParam_3)); + if (event != NULL) + { + event->base.EventID = eventID | PARAM_COUNT(3); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + event->param1 = (uint32_t)param1; + event->param2 = param2; + event->param3 = param3; + TRC_STREAM_PORT_COMMIT_EVENT(event, sizeof(EventWithParam_3)); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Stores an event with 32-bit integer parameters */ +void prvTraceStoreEvent(int nParam, uint16_t eventID, ...) +{ + va_list vl; + int i; + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + int eventSize = (int)sizeof(BaseEvent) + nParam * (int)sizeof(uint32_t); + + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize); + if (event != NULL) + { + event->base.EventID = eventID | (uint16_t)PARAM_COUNT(nParam); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + + va_start(vl, eventID); + for (i = 0; i < nParam; i++) + { + uint32_t* tmp = (uint32_t*) &(event->data[i]); + *tmp = va_arg(vl, uint32_t); + } + va_end(vl); + + TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize); + } + } + } + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Stories an event with a string and 32-bit integer parameters */ +void prvTraceStoreStringEvent(int nArgs, uint16_t eventID, const char* str, ...) +{ + va_list vl; + + va_start(vl, str); + prvTraceStoreStringEventHelper(nArgs, eventID, NULL, str, &vl); + va_end(vl); +} + +/* Internal common function for storing string events */ +static void prvTraceStoreStringEventHelper( int nArgs, + uint16_t eventID, + traceString userEvtChannel, + const char* str, va_list* vl) +{ + int len; + int nWords; + int nStrWords; + int i; + int offset = 0; + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */ + + /* The string length in multiples of 32 bit words (+1 for null character) */ + nStrWords = (len+1+3)/4; + + /* If a user event channel is specified, add in the list */ + if (userEvtChannel) + nArgs++; + + offset = nArgs * 4; + + /* The total number of 32-bit words needed for the whole payload */ + nWords = nStrWords + nArgs; + + if (nWords > 15) /* if attempting to store more than 60 byte (= max) */ + { + /* Truncate event if too large. The string characters are stored + last, so usually only the string is truncated, unless there a lot + of parameters... */ + + /* Diagnostics ... */ + uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4; + + if (bytesTruncated > MaxBytesTruncated) + { + MaxBytesTruncated = bytesTruncated; + } + + nWords = 15; + len = 15 * 4 - offset; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t); + + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize); + if (event != NULL) + { + uint32_t* data32; + uint8_t* data8; + event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + + /* 32-bit write-pointer for the data argument */ + data32 = (uint32_t*) &(event->data[0]); + + for (i = 0; i < nArgs; i++) + { + if ((userEvtChannel != NULL) && (i == 0)) + { + /* First, add the User Event Channel if not NULL */ + data32[i] = (uint32_t)userEvtChannel; + } + else + { + /* Add data arguments... */ + data32[i] = va_arg(*vl, uint32_t); + } + } + data8 = (uint8_t*)&(event->data[0]); + for (i = 0; i < len; i++) + { + data8[offset + i] = str[i]; + } + + if (len < (15 * 4 - offset)) + data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */ + TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize); + } + } + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Internal common function for storing string events without additional arguments */ +void prvTraceStoreSimpleStringEventHelper(traceString userEvtChannel, + const char* str) +{ + int len; + int nWords; + int nStrWords; + int i; + int nArgs = 0; + int offset = 0; + uint16_t eventID = PSF_EVENT_USER_EVENT; + TRACE_ALLOC_CRITICAL_SECTION(); + + PSF_ASSERT(eventID < 4096, PSF_ERROR_EVENT_CODE_TOO_LARGE); + + for (len = 0; (str[len] != 0) && (len < 52); len++); /* empty loop */ + + /* The string length in multiples of 32 bit words (+1 for null character) */ + nStrWords = (len+1+3)/4; + + /* If a user event channel is specified, add in the list */ + if (userEvtChannel) + { + nArgs++; + eventID++; + } + + offset = nArgs * 4; + + /* The total number of 32-bit words needed for the whole payload */ + nWords = nStrWords + nArgs; + + if (nWords > 15) /* if attempting to store more than 60 byte (= max) */ + { + /* Truncate event if too large. The string characters are stored + last, so usually only the string is truncated, unless there a lot + of parameters... */ + + /* Diagnostics ... */ + uint32_t bytesTruncated = (uint32_t)(nWords - 15) * 4; + + if (bytesTruncated > MaxBytesTruncated) + { + MaxBytesTruncated = bytesTruncated; + } + + nWords = 15; + len = 15 * 4 - offset; + } + + TRACE_ENTER_CRITICAL_SECTION(); + + if (RecorderEnabled) + { + int eventSize = (int)sizeof(BaseEvent) + nWords * (int)sizeof(uint32_t); + + eventCounter++; + + { + TRC_STREAM_PORT_ALLOCATE_DYNAMIC_EVENT(largestEventType, event, eventSize); + if (event != NULL) + { + uint32_t* data32; + uint8_t* data8; + event->base.EventID = (eventID) | (uint16_t)PARAM_COUNT(nWords); + event->base.EventCount = (uint16_t)eventCounter; + event->base.TS = prvGetTimestamp32(); + + /* 32-bit write-pointer for the data argument */ + data32 = (uint32_t*) &(event->data[0]); + + if (userEvtChannel != NULL) + { + /* First, add the User Event Channel if not NULL */ + data32[0] = (uint32_t)userEvtChannel; + } + + data8 = (uint8_t*) &(event->data[0]); + for (i = 0; i < len; i++) + { + data8[offset + i] = str[i]; + } + + if (len < (15 * 4 - offset)) + data8[offset + len] = 0; /* Only truncate if we don't fill up the buffer completely */ + TRC_STREAM_PORT_COMMIT_EVENT(event, (uint32_t)eventSize); + } + } + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Saves a symbol name (task name etc.) in symbol table */ +void prvTraceSaveSymbol(const void *address, const char *name) +{ + uint32_t i; + uint32_t foundSlot; + uint32_t *ptrAddress; + uint8_t *ptrSymbol; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + foundSlot = firstFreeSymbolTableIndex; + + /* First look for previous entries using this address */ + for (i = 0; i < firstFreeSymbolTableIndex; i += SYMBOL_TABLE_SLOT_SIZE) + { + /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */ + ptrAddress = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i / sizeof(uint32_t)]; + if (*ptrAddress == (uint32_t)address) + { + foundSlot = i; + break; + } + } + + if (foundSlot < SYMBOL_TABLE_BUFFER_SIZE) + { + /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */ + symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[foundSlot / sizeof(uint32_t)] = (uint32_t)address; + + /* We access the symbol table via the union member pSymbolTableBufferUINT8 to avoid strict-aliasing issues */ + ptrSymbol = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT8[foundSlot + sizeof(uint32_t)]; + for (i = 0; i < (TRC_CFG_SYMBOL_MAX_LENGTH); i++) + { + ptrSymbol[i] = (uint8_t)name[i]; /* We do this first to ensure we also get the 0 termination, if there is one */ + + if (name[i] == 0) + break; + } + + /* Check the length of "name", if longer than SYMBOL_MAX_LENGTH */ + while ((name[i] != 0) && i < 128) + { + i++; + } + + /* Remember the longest symbol name, for diagnostic purposes */ + if (i > LongestSymbolName) + { + LongestSymbolName = i; + } + + /* Is this the last entry in the symbol table? */ + if (foundSlot == firstFreeSymbolTableIndex) + { + firstFreeSymbolTableIndex += SYMBOL_TABLE_SLOT_SIZE; + } + } + else + { + NoRoomForSymbol++; + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Deletes a symbol name (task name etc.) from symbol table */ +void prvTraceDeleteSymbol(void *address) +{ + uint32_t i, j; + uint32_t *ptr, *lastEntryPtr; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + for (i = 0; i < firstFreeSymbolTableIndex; i += SYMBOL_TABLE_SLOT_SIZE) + { + /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */ + ptr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[i / sizeof(uint32_t)]; + if (*ptr == (uint32_t)address) + { + /* See if we have another entry in the table, and that this isn't already the last entry */ + if (firstFreeSymbolTableIndex > SYMBOL_TABLE_SLOT_SIZE && i != (firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE)) + { + /* Another entry is available, get pointer to the last one */ + /* We access the symbol table via the union member pSymbolTableBufferUINT32 to avoid strict-aliasing issues */ + lastEntryPtr = &symbolTable.SymbolTableBuffer.pSymbolTableBufferUINT32[(firstFreeSymbolTableIndex - SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t)]; + + /* Copy last entry to this position */ + for (j = 0; j < (SYMBOL_TABLE_SLOT_SIZE) / sizeof(uint32_t); j++) + { + ptr[j] = lastEntryPtr[j]; + } + + /* For good measure we also zero out the original position */ + *lastEntryPtr = 0; + } + else + *ptr = 0; /* No other entry found, or this is the last entry */ + + /* Lower index */ + firstFreeSymbolTableIndex -= SYMBOL_TABLE_SLOT_SIZE; + + break; + } + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Saves an object data entry (current task priority) in object data table */ +void prvTraceSaveObjectData(const void *address, uint32_t data) +{ + uint32_t i; + uint32_t foundSlot; + uint32_t *ptr; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + foundSlot = firstFreeObjectDataTableIndex; + + /* First look for previous entries using this address */ + for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE) + { + /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */ + ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)]; + if (*ptr == (uint32_t)address) + { + foundSlot = i; + break; + } + } + + if (foundSlot < OBJECT_DATA_TABLE_BUFFER_SIZE) + { + /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */ + objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t)] = (uint32_t)address; + objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[foundSlot / sizeof(uint32_t) + 1] = data; + + /* Is this the last entry in the object data table? */ + if (foundSlot == firstFreeObjectDataTableIndex) + { + firstFreeObjectDataTableIndex += OBJECT_DATA_SLOT_SIZE; + } + } + else + { + NoRoomForObjectData++; + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Removes an object data entry (task base priority) from object data table */ +void prvTraceDeleteObjectData(void *address) +{ + uint32_t i, j; + uint32_t *ptr, *lastEntryPtr; + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + + for (i = 0; i < firstFreeObjectDataTableIndex; i += OBJECT_DATA_SLOT_SIZE) + { + /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */ + ptr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[i / sizeof(uint32_t)]; + if (*ptr == (uint32_t)address) + { + /* See if we have another entry in the table, and that this isn't already the last entry */ + if (firstFreeObjectDataTableIndex > OBJECT_DATA_SLOT_SIZE && i != (firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE)) + { + /* Another entry is available, get pointer to the last one */ + /* We access the data table via the union member pObjectDataTableBufferUINT32 to avoid strict-aliasing issues */ + lastEntryPtr = &objectDataTable.ObjectDataTableBuffer.pObjectDataTableBufferUINT32[(firstFreeObjectDataTableIndex - OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t)]; + + /* Copy last entry to this position */ + for (j = 0; j < (OBJECT_DATA_SLOT_SIZE) / sizeof(uint32_t); j++) + { + ptr[j] = lastEntryPtr[j]; + } + + /* For good measure we also zero out the original position */ + *lastEntryPtr = 0; + } + else + *ptr = 0; /* No other entry found, or this is the last entry */ + + /* Lower index */ + firstFreeObjectDataTableIndex -= OBJECT_DATA_SLOT_SIZE; + + break; + } + } + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Checks if the provided command is a valid command */ +int prvIsValidCommand(TracealyzerCommandType* cmd) +{ + uint16_t checksum = (uint16_t)(0xFFFF - ( cmd->cmdCode + + cmd->param1 + + cmd->param2 + + cmd->param3 + + cmd->param4 + + cmd->param5)); + + if (cmd->checksumMSB != (unsigned char)(checksum >> 8)) + return 0; + + if (cmd->checksumLSB != (unsigned char)(checksum & 0xFF)) + return 0; + + if (cmd->cmdCode > CMD_LAST_COMMAND) + return 0; + + return 1; +} + +/* Executed the received command (Start or Stop) */ +void prvProcessCommand(TracealyzerCommandType* cmd) +{ + switch(cmd->cmdCode) + { + case CMD_SET_ACTIVE: + prvSetRecorderEnabled(cmd->param1); + break; + default: + break; + } +} + +/* Called on warnings, when the recording can continue. */ +void prvTraceWarning(int errCode) +{ + if (!errorCode) + { + errorCode = errCode; + prvTraceStoreWarnings(); + } +} + +/* Called on critical errors in the recorder. Stops the recorder! */ +void prvTraceError(int errCode) +{ + if (! errorCode) + { + errorCode = errCode; + prvTraceStoreWarnings(); +#if TRC_CFG_INCLUDE_USER_EVENTS /* << EST only available if TRC_CFG_INCLUDE_USER_EVENTS is turned on */ + vTracePrintF(trcWarningChannel, "Recorder stopped in prvTraceError()"); +#endif + + prvSetRecorderEnabled(0); + } +} + +/* If using DWT timestamping (default on ARM Cortex-M3, M4 and M7), make sure the DWT unit is initialized. */ +#ifndef TRC_CFG_ARM_CM_USE_SYSTICK +#if ((TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_ARM_Cortex_M) && (defined (__CORTEX_M) && (__CORTEX_M >= 0x03))) + +void prvTraceInitCortexM() +{ + /* Make sure the DWT registers are unlocked, in case the debugger doesn't do this. */ + TRC_REG_ITM_LOCKACCESS = TRC_ITM_LOCKACCESS_UNLOCK; + + /* Make sure DWT is enabled is enabled, if supported */ + TRC_REG_DEMCR |= TRC_DEMCR_TRCENA; + + do + { + /* Verify that DWT is supported */ + if (TRC_REG_DEMCR == 0) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + + If the below error is produced, the DWT unit does not seem to be available. + + In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + to use SysTick timestamping instead, or define your own timestamping by + setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError(PSF_ERROR_DWT_NOT_SUPPORTED); + break; + } + + /* Verify that DWT_CYCCNT is supported */ + if (TRC_REG_DWT_CTRL & TRC_DWT_CTRL_NOCYCCNT) + { + /* This function is called on Cortex-M3, M4 and M7 devices to initialize + the DWT unit, assumed present. The DWT cycle counter is used for timestamping. + + If the below error is produced, the cycle counter does not seem to be available. + + In that case, define the macro TRC_CFG_ARM_CM_USE_SYSTICK in your build + to use SysTick timestamping instead, or define your own timestamping by + setting TRC_CFG_HARDWARE_PORT to TRC_HARDWARE_PORT_APPLICATION_DEFINED + and make the necessary definitions, as explained in trcHardwarePort.h.*/ + + prvTraceError(PSF_ERROR_DWT_CYCCNT_NOT_SUPPORTED); + break; + } + + /* Reset the cycle counter */ + TRC_REG_DWT_CYCCNT = 0; + + /* Enable the cycle counter */ + TRC_REG_DWT_CTRL |= TRC_DWT_CTRL_CYCCNTENA; + + } while(0); /* breaks above jump here */ +} +#endif +#endif + +/* Performs timestamping using definitions in trcHardwarePort.h */ +static uint32_t prvGetTimestamp32(void) +{ +#if ((TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_INCR) || (TRC_HWTC_TYPE == TRC_FREE_RUNNING_32BIT_DECR)) + return TRC_HWTC_COUNT; +#endif + +#if ((TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR)) + return TRC_HWTC_COUNT; +#endif + +#if ((TRC_HWTC_TYPE == TRC_OS_TIMER_INCR) || (TRC_HWTC_TYPE == TRC_OS_TIMER_DECR)) + uint32_t ticks = TRACE_GET_OS_TICKS(); + return (TRC_HWTC_COUNT & 0x00FFFFFFU) + ((ticks & 0x000000FFU) << 24); +#endif +} + +/* Store the Timestamp Config event */ +static void prvTraceStoreTSConfig(void) +{ + /* If not overridden using vTraceSetFrequency, use default value */ + if (timestampFrequency == 0) + { + timestampFrequency = TRC_HWTC_FREQ_HZ; + } + + #if (TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR) + + prvTraceStoreEvent(5, + PSF_EVENT_TS_CONFIG, + (uint32_t)timestampFrequency, + (uint32_t)TRACE_TICK_RATE_HZ, + (uint32_t)TRC_HWTC_TYPE, + (uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD, + (uint32_t)TRC_HWTC_PERIOD); + + #else + + prvTraceStoreEvent(4, + PSF_EVENT_TS_CONFIG, + (uint32_t)timestampFrequency, + (uint32_t)TRACE_TICK_RATE_HZ, + (uint32_t)TRC_HWTC_TYPE, + (uint32_t)TRC_CFG_ISR_TAILCHAINING_THRESHOLD); + #endif +} + +/* Retrieve a buffer page to write to. */ +static int prvAllocateBufferPage(int prevPage) +{ + int index; + int count = 0; + + index = (prevPage + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT; + + while((PageInfo[index].Status != PAGE_STATUS_FREE) && (count ++ < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)) + { + index = (index + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT; + } + + if (PageInfo[index].Status == PAGE_STATUS_FREE) + { + return index; + } + + return -1; +} + +/* Mark the page read as complete. */ +static void prvPageReadComplete(int pageIndex) +{ + TRACE_ALLOC_CRITICAL_SECTION(); + + TRACE_ENTER_CRITICAL_SECTION(); + PageInfo[pageIndex].BytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; + PageInfo[pageIndex].WritePointer = &EventBuffer[pageIndex * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; + PageInfo[pageIndex].Status = PAGE_STATUS_FREE; + + TotalBytesRemaining += TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; + + TRACE_EXIT_CRITICAL_SECTION(); +} + +/* Get the current buffer page index and remaining number of bytes. */ +static int prvGetBufferPage(int32_t* bytesUsed) +{ + static int8_t lastPage = -1; + int count = 0; + int8_t index = (int8_t) ((lastPage + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT); + + while((PageInfo[index].Status != PAGE_STATUS_READ) && (count++ < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT)) + { + index = (int8_t)((index + 1) % TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT); + } + + if (PageInfo[index].Status == PAGE_STATUS_READ) + { + *bytesUsed = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE - PageInfo[index].BytesRemaining; + lastPage = index; + return index; + } + + *bytesUsed = 0; + + return -1; +} + +/******************************************************************************* + * uint32_t prvPagedEventBufferTransfer(void) + * + * Transfers one buffer page of trace data, if a full page is available, using + * the macro TRC_STREAM_PORT_WRITE_DATA as defined in trcStreamingPort.h. + * + * This function is intended to be called the periodic TzCtrl task with a suitable + * delay (e.g. 10-100 ms). + * + * Returns the number of bytes sent. If non-zero, it is good to call this + * again, in order to send any additional data waiting in the buffer. + * If zero, wait a while before calling again. + * + * In case of errors from the streaming interface, it registers a warning + * (PSF_WARNING_STREAM_PORT_WRITE) provided by xTraceGetLastError(). + * + *******************************************************************************/ +uint32_t prvPagedEventBufferTransfer(void) +{ + int8_t pageToTransfer = -1; + int32_t bytesTransferredTotal = 0; + int32_t bytesTransferredNow = 0; + int32_t bytesToTransfer; + + pageToTransfer = (int8_t)prvGetBufferPage(&bytesToTransfer); + + /* bytesToTransfer now contains the number of "valid" bytes in the buffer page, that should be transmitted. + There might be some unused junk bytes in the end, that must be ignored. */ + + if (pageToTransfer > -1) + { + while (1) /* Keep going until we have transferred all that we intended to */ + { + if (TRC_STREAM_PORT_WRITE_DATA( + &EventBuffer[pageToTransfer * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE + bytesTransferredTotal], + (uint32_t)(bytesToTransfer - bytesTransferredTotal), + &bytesTransferredNow) == 0) + { + /* Write was successful. Update the number of transferred bytes. */ + bytesTransferredTotal += bytesTransferredNow; + + if (bytesTransferredTotal == bytesToTransfer) + { + /* All bytes have been transferred. Mark the buffer page as "Read Complete" (so it can be written to) and return OK. */ + prvPageReadComplete(pageToTransfer); + return (uint32_t)bytesTransferredTotal; + } + } + else + { + /* Some error from the streaming interface... */ + prvTraceWarning(PSF_WARNING_STREAM_PORT_WRITE); + return 0; + } + } + } + return 0; +} + +/******************************************************************************* + * void* prvPagedEventBufferGetWritePointer(int sizeOfEvent) + * + * Returns a pointer to an available location in the buffer able to store the + * requested size. + * + * Return value: The pointer. + * + * Parameters: + * - sizeOfEvent: The size of the event that is to be placed in the buffer. + * +*******************************************************************************/ +void* prvPagedEventBufferGetWritePointer(int sizeOfEvent) +{ + void* ret; + static int currentWritePage = -1; + + if (currentWritePage == -1) + { + currentWritePage = prvAllocateBufferPage(currentWritePage); + if (currentWritePage == -1) + { + DroppedEventCounter++; + return NULL; + } + } + + if (PageInfo[currentWritePage].BytesRemaining - sizeOfEvent < 0) + { + PageInfo[currentWritePage].Status = PAGE_STATUS_READ; + + TotalBytesRemaining -= PageInfo[currentWritePage].BytesRemaining; // Last trailing bytes + + if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark) + TotalBytesRemaining_LowWaterMark = TotalBytesRemaining; + + currentWritePage = prvAllocateBufferPage(currentWritePage); + if (currentWritePage == -1) + { + DroppedEventCounter++; + return NULL; + } + } + ret = PageInfo[currentWritePage].WritePointer; + PageInfo[currentWritePage].WritePointer += sizeOfEvent; + PageInfo[currentWritePage].BytesRemaining = (uint16_t)(PageInfo[currentWritePage].BytesRemaining -sizeOfEvent); + + TotalBytesRemaining = (TotalBytesRemaining-(uint16_t)sizeOfEvent); + + if (TotalBytesRemaining < TotalBytesRemaining_LowWaterMark) + TotalBytesRemaining_LowWaterMark = TotalBytesRemaining; + + return ret; +} + +/******************************************************************************* + * void prvPagedEventBufferInit(char* buffer) + * + * Assigns the buffer to use and initializes the PageInfo structure. + * + * Return value: void + * + * Parameters: + * - char* buffer: pointer to the trace data buffer, allocated by the caller. + * +*******************************************************************************/ +void prvPagedEventBufferInit(char* buffer) +{ + int i; + TRACE_ALLOC_CRITICAL_SECTION(); + + EventBuffer = buffer; + + TRACE_ENTER_CRITICAL_SECTION(); + for (i = 0; i < TRC_CFG_PAGED_EVENT_BUFFER_PAGE_COUNT; i++) + { + PageInfo[i].BytesRemaining = TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE; + PageInfo[i].WritePointer = &EventBuffer[i * TRC_CFG_PAGED_EVENT_BUFFER_PAGE_SIZE]; + PageInfo[i].Status = PAGE_STATUS_FREE; + } + TRACE_EXIT_CRITICAL_SECTION(); + +} + +#endif /*(TRC_USE_TRACEALYZER_RECORDER == 1)*/ + +#endif /*(TRC_CFG_RECORDER_MODE == TRC_RECORDER_MODE_STREAMING)*/ + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/types.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/types.h new file mode 100644 index 0000000..836ec8d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/types.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file types.h + * + * @author + * + * @version + * + * @date + * + * @brief The file contains definitions of datatypes. + * + *****************************************************************************/ + + +#ifndef _TYPES_H +#define _TYPES_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define LSB(a) ((a)._byte.byte0) +#define MSB(a) ((a)._byte.byte1) + +#define LOWER_LSB(a) ((a)._byte.byte0) +#define LOWER_MSB(a) ((a)._byte.byte1) +#define UPPER_LSB(a) ((a)._byte.byte2) +#define UPPER_MSB(a) ((a)._byte.byte3) + +#define _PTR_ * +#define _CODE_PTR_ * + +#ifndef TRUE +#define FALSE 0 +#define TRUE 1 +#endif + +#define BYTESWAP16(x) (uint_16)((((x) & 0xFF00) >> 0x8) | (((x) & 0xFF) << 0x8)) +#define BYTESWAP32(val) (uint_32)((BYTESWAP16((uint_32)(val) & (uint_32)0xFFFF) << 0x10) | \ + (BYTESWAP16((uint_32)((val) >> 0x10)))) + +#ifdef __HIWARE__ /* define macros used below to avoid warnings for S08 */ + #define __ORDER_LITTLE_ENDIAN__ 0 + #define __BYTE_ORDER__ 1 + #define BIG_ENDIAN +#endif + +#ifdef CPU_LITTLE_ENDIAN /* << EST: defined by Processor Expert CPU.h for Kinetis devices (but NOT in for SDK 1.x!) */ + #ifndef LITTLE_ENDIAN /* might be defined already on the compiler command line? */ + #define LITTLE_ENDIAN + #endif +#elif defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* GNU/gcc provides these macros */ + #define LITTLE_ENDIAN +#endif + +#ifndef LITTLE_ENDIAN +#define ieee_htons(x) (uint_16)(x) +#define ieee_htonl(x) (uint_32)(x) +#define ieee_ntohs(x) (uint_16)(x) +#define ieee_ntohl(x) (uint_32)(x) +#else +#define ieee_htons(x) BYTESWAP16(x) +#define ieee_htonl(x) BYTESWAP32(x) +#define ieee_ntohs(x) BYTESWAP16(x) +#define ieee_ntohl(x) BYTESWAP32(x) +#endif + +#define UNUSED(x) (void)x; +/****************************************************************************** + * Types + *****************************************************************************/ +typedef void _PTR_ pointer; /* Machine representation of a pointer */ +typedef unsigned char uint_8; /* 8-bit*/ +typedef signed char int_8; /* 8-bit*/ + +typedef unsigned short uint_16; /* 16-bit*/ +typedef signed short int_16; /* 16-bit*/ + +typedef unsigned long uint_32; /* 32-bit*/ +typedef signed long int_32; /* 32-bit*/ + +typedef unsigned char boolean; /* 8-bit*/ + +typedef uint_8* uint_8_ptr; /* ptr to 8-bit*/ +typedef uint_16* uint_16_ptr; /* ptr to 16-bit */ +typedef uint_32* uint_32_ptr; /* ptr to 32-bit*/ + +typedef uint_8_ptr uchar_ptr; /* ptr to 8-bit*/ + + +/****************************************************************************** + * Global Functions - None + *****************************************************************************/ + +#endif + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_bdt_kinetis.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_bdt_kinetis.h new file mode 100644 index 0000000..d73c85d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_bdt_kinetis.h @@ -0,0 +1,140 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_bdt_kinetis.h + * + * @author + * + * @version + * + * @date Jun-05-2009 + * + * @brief The file contains definitions of Buffer Descriptor Table. + * + *****************************************************************************/ + +#ifndef _USBBDT_H +#define _USBBDT_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +/* Buffer Descriptor Status Register Initialization Parameters */ +#define _BDTSTALL (0x04) /* Buffer Stall enable */ +#define _DATA0 (0x00) /* DATA0 packet expected next */ +#define _DATA1 (0x40) /* DATA1 packet expected next */ +#define _DTS (0x08) /* DTS Mask */ +#define _SIE (0x80) /* SIE owns buffer */ +#define _CPU (0x00) /* CPU owns buffer */ +#define _KEEP (0x20) /* keep bit */ + +#define MAX_BDT_INDEX (64) /* Maximum BDT Indexes */ + + +/****************************************************************************** + * Types + *****************************************************************************/ + /* This structure is an exact replica of the BDT MAP in the USB RAM + The BDT_STAT defines the stat byte of the buffer descriptor vector. + McuCtlBit structure defines the bits that have a meaning from CPU + point of view.SieCtlBit structure defines the bits that have a + meaning from USB controller point of view. + */ + +#if defined(__CWCC__) +#pragma align_array_members on +#endif +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) +typedef struct _MCU_CTL_BIT{ + uint_8 :1; + uint_8 :1; + uint_8 bdtstall:1; /* Buffer Stall Enable */ + uint_8 dts:1; /* Data Toggle Synch Enable */ + uint_8 keep:1; /* Address Increment Disable */ + uint_8 ninc:1; /* BD Keep Enable */ + uint_8 data:1; /* Data Toggle Synch Value */ + uint_8 own:1; /* USB Ownership */ +}MCU_CTL_BIT; /* read Stat */ + +typedef struct _SIE_CTL_BIT{ + uint_8 :1; + uint_8 :1; + uint_8 pid0:1; /* Packet Identifier bit 0 */ + uint_8 pid1:1; /* Packet Identifier bit 1 */ + uint_8 pid2:1; /* Packet Identifier bit 2 */ + uint_8 pid3:1; /* Packet Identifier bit 3 */ + uint_8 :1; + uint_8 own:1; +}SIE_CTL_BIT; /* write Stat */ + +typedef struct _REC_PID{ + uint_8 :2; + uint_8 pid:4; /* Packet Identifier */ + uint_8 :2; +}REC_PID; + +typedef union _BD_STAT +{ + uint_8 _byte; + MCU_CTL_BIT McuCtlBit; + SIE_CTL_BIT SieCtlBit; + REC_PID RecPid; +} BD_STAT; /* Buffer Descriptor Status Register */ + +typedef struct _BUFF_DSC +{ + BD_STAT Stat; + uint_8 reserved1; + uint_16 cnt; /* Count of bytes receieved or sent */ + /* six MSB bits are reserved ones */ + uint_32 addr; /* Buffer Address */ +} BUFF_DSC, *P_BUFF_DSC; /* Buffer Descriptor Table */ + +typedef struct _g_bdtmap { + + BUFF_DSC ep_dsc[MAX_BDT_INDEX]; /* Endpoint Descriptor */ +}BDTMAP; +#if defined(__CWCC__) +#pragma align_array_members off +#pragma options align=reset +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma pack() +#else /* e.g. gcc */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#endif +/****************************************************************************** + * Global Functions - None + *****************************************************************************/ + +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.c new file mode 100644 index 0000000..82388e0 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.c @@ -0,0 +1,809 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack CDC layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_cdc.h" /* USB CDC Class Header File */ +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef _MC9S08JS16_H +#pragma DATA_SEG APP_DATA +#endif + +/* CDC Class Callback Function Pointer */ +static USB_CLASS_CALLBACK g_cdc_class_callback = NULL; + +/* CDC Class Vendor Callback Function Pointer */ +static USB_REQ_FUNC g_vendor_req_callback = NULL; + +/* CDC endpoint info array */ +#ifndef COMPOSITE_DEV +static USB_CLASS_CDC_ENDPOINT g_cdc_ep[CDC_DESC_ENDPOINT_COUNT]; +#else +static USB_CLASS_CDC_ENDPOINT g_cdc_ep[COMPOSITE_DESC_ENDPOINT_COUNT]; +#endif +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +#if CIC_NOTIF_ELEM_SUPPORT +void USB_Class_CDC_Service_Cic_Notify(PTR_USB_DEV_EVENT_STRUCT event); +#endif +#if !DIC_ISOCHRONOUS_SETTING +void USB_Class_CDC_Service_Dic_Bulk_In(PTR_USB_DEV_EVENT_STRUCT event); +void USB_Class_CDC_Service_Dic_Bulk_Out(PTR_USB_DEV_EVENT_STRUCT event); +#else +static void USB_Class_CDC_Service_Dic_Iso_In(PTR_USB_DEV_EVENT_STRUCT event); +static void USB_Class_CDC_Service_Dic_Iso_Out(PTR_USB_DEV_EVENT_STRUCT event); +#endif +#ifndef COMPOSITE_DEV +static uint_8 USB_Other_Requests( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +#endif + void USB_Class_CDC_Event( + uint_8 controller_ID, + uint_8 event, + void* val); + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + + /***************************************************************************** + * Local Functions + *****************************************************************************/ +#if CIC_NOTIF_ELEM_SUPPORT +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Cic_Notify + * + * @brief The function is callback function of CIC Notification endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower layer when data on CIC Endpoint is sent + *****************************************************************************/ +void USB_Class_CDC_Service_Cic_Notify ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + break; + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + + if(g_cdc_class_callback != NULL) + { + uint_8 event_type = USB_APP_SEND_COMPLETE; + + if(event->errors != 0) + { + event_type = USB_APP_ERROR; + } + g_cdc_class_callback(event->controller_ID, event_type, + (uint_8*)(&(event->errors))); + } +} +#endif + +#if !DIC_ISOCHRONOUS_SETTING +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Bulk_In + * + * @brief The function is callback function of DIC Bulk In Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC SEND Interface is sent + *****************************************************************************/ +void USB_Class_CDC_Service_Dic_Bulk_In ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT bulk_in_recv; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + bulk_in_recv.data_ptr = event->buffer_ptr; + bulk_in_recv.data_size = event->len; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + break; + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, + (void*)&bulk_in_recv); + } + } +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Bulk_Out + * + * @brief The function is callback function of DIC Bulk Out Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC RECV Interface is received + *****************************************************************************/ +void USB_Class_CDC_Service_Dic_Bulk_Out ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ APP_DATA_STRUCT bulk_out_recv; + + bulk_out_recv.data_ptr = event->buffer_ptr; + bulk_out_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_DATA_RECEIVED, + (void*)&bulk_out_recv); + } + } +} + +#else +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Iso_In + * + * @brief The function is callback function of DIC Isochronous In Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC SEND Interface is sent + *****************************************************************************/ +static void USB_Class_CDC_Service_Dic_Iso_In ( + PTR_USB_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT iso_in_recv; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(event->controller_ID); + + USB_CLASS_CDC_QUEUE queue; + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == event->ep_num) + { + break; + } + } + + producer = g_cdc_ep[index].bin_producer; + + /* if there are no errors de-queue the queue and decrement the no. of + transfers left, else send the same data again */ + if(event->errors == 0) + { + g_cdc_ep[index].bin_consumer++; + } + + consumer = g_cdc_ep[index].bin_consumer; + + if(consumer != producer) + {/*if bin is not empty */ + + queue = g_cdc_ep[index].queue[consumer%MAX_QUEUE_ELEMS]; + + (void)USB_Class_Send_Data(queue.controller_ID, queue.channel, + queue.app_data.data_ptr, queue.app_data.data_size); + } +#endif + + iso_in_recv.data_ptr = event->buffer_ptr; + iso_in_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_SEND_COMPLETE, + (void*)&iso_in_recv); + } + } +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Service_Dic_Iso_Out + * + * @brief This is a callback function of DIC Isochronous Out Endpoint + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * Called by Lower Layer when Data on DIC RECV Interface is received + *****************************************************************************/ +static void USB_Class_CDC_Service_Dic_Iso_Out ( + PTR_USB_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + APP_DATA_STRUCT iso_out_recv; + + iso_out_recv.data_ptr = event->buffer_ptr; + iso_out_recv.data_size = event->len; + + if(g_cdc_class_callback != NULL) + { + if(event->errors != 0) + { + g_cdc_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + } + else + { + g_cdc_class_callback(event->controller_ID, USB_APP_DATA_RECEIVED, + (void*)&iso_out_recv); + } + } +} +#endif +/**************************************************************************//*! + * + * @name USB_Class_CDC_Event + * + * @brief The function initializes CDC endpoints + * + * @param controller_ID : Controller ID + * @param event : Event Type + * @param val : Pointer to configuration Value + * + * @return None + * + ****************************************************************************** + * + *****************************************************************************/ +void USB_Class_CDC_Event ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 event, /* [IN] Event Type */ + void* val /* [OUT] Pointer to configuration Value */ +) +{ + uint_8 index; + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(controller_ID); + + if(event == USB_APP_ENUM_COMPLETE) + { + uint_8 count = 0,ep_count = 0; + uint_8 index_num = 0; + +#ifdef COMPOSITE_DEV + DEV_ARCHITECTURE_STRUCT_PTR dev_arc_ptr; + CLASS_ARC_STRUCT_PTR dev_class_ptr; + dev_arc_ptr = (DEV_ARCHITECTURE_STRUCT *)USB_Desc_Get_Class_Architecture(controller_ID); + for(count = 0; count < dev_arc_ptr->cl_count; count++) + { + dev_class_ptr = (CLASS_ARC_STRUCT_PTR)dev_arc_ptr->value[count]; + /* Initializes sub_classes */ + ep_count = dev_class_ptr->value[0]; + if(dev_class_ptr->class_type == 0x02/*CDC_CC*/) + break; + index_num +=dev_class_ptr->value[0]; + } +#else + ep_count = usb_ep_data->count; +#endif + + for(count=index_num; countep[count]); + (void)_usb_device_deinit_endpoint(&controller_ID, + ep_struct_ptr->ep_num, ep_struct_ptr->direction); + } + + /* intialize all non control endpoints */ + for(count=index_num; countep[count]); + + (void)_usb_device_init_endpoint(&controller_ID, ep_struct->ep_num, + ep_struct->size, ep_struct->direction, ep_struct->type, FALSE); + + /* register callback service for Non Control EndPoints */ + switch(ep_struct->type) + { +#if CIC_NOTIF_ELEM_SUPPORT + case USB_INTERRUPT_PIPE : + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Cic_Notify); + break; +#endif +#if !DIC_ISOCHRONOUS_SETTING + case USB_BULK_PIPE : +#ifdef MULTIPLE_DEVICES + if(ep_struct->direction == USB_RECV) + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Bulk_Out); + } + else + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Bulk_In); + } +#endif + break; +#else + case USB_ISOCHRONOUS_PIPE : + if(ep_struct->direction == USB_RECV) + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Iso_Out); + } + else + { + (void)_usb_device_register_service(controller_ID, + (uint_8)(USB_SERVICE_EP0+ep_struct->ep_num), + USB_Class_CDC_Service_Dic_Iso_In); + } + break; +#endif + default: + break; + } + /* set the EndPoint Status as Idle in the device layer */ + (void)_usb_device_set_status(&controller_ID, + (uint_8)(USB_STATUS_ENDPOINT | ep_struct->ep_num | + (ep_struct->direction << USB_COMPONENT_DIRECTION_SHIFT)), + (uint_8)USB_STATUS_IDLE); + } + } + else if(event == USB_APP_BUS_RESET) + { +#if IMPLEMENT_QUEUING + for(index = 0; index < usb_ep_data->count; index++) + { + g_cdc_ep[index].bin_consumer = 0x00; + g_cdc_ep[index].bin_producer = 0x00; + } +#endif + } + if(g_cdc_class_callback != NULL) + { + g_cdc_class_callback(controller_ID, event, val); + } +} + +/**************************************************************************//*! + * + * @name USB_Other_Requests + * + * @brief The function provides flexibilty to add class and vendor specific + * requests + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data: : Data to be send back + * @param size: : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * Handles CDC Class requests and forwards vendor specific request to the + * application + *****************************************************************************/ +#ifndef COMPOSITE_DEV +static uint_8 USB_Other_Requests +#else +uint_8 USB_CDC_Other_Requests +#endif +( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet,/* [IN] Pointer to Setup Packet Received */ + uint_8_ptr *data, /* [OUT] Pointer to Data Buffer to be sent */ + USB_PACKET_SIZE *size /* [OUT] Size of Data buffer */ +) +{ + uint_8 status = USBERR_INVALID_REQ_TYPE; + if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_CLASS) + { + /* class request so handle it here */ + status=USB_OK; + + /* call for class/subclass specific requests */ + switch(setup_packet->request) + { + case SEND_ENCAPSULATED_COMMAND : + /* Add code to transfer Request and Acknowledgement */ + *size=0; + break; + case GET_ENCAPSULATED_RESPONSE : + /* + Add code for handling Transfer Response/Requests and + Notification + */ + *size=0; + break; + case SET_COMM_FEATURE : + status = USB_Class_CDC_PSTN_Set_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case GET_COMM_FEATURE : + status = USB_Class_CDC_PSTN_Get_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case CLEAR_COMM_FEATURE : /* Verify this implementation */ + *size = COMM_FEATURE_DATA_SIZE; + **data = 0x00; *(++(*data)) = 0x00;/* clear both feature bytes */ + status = USB_Class_CDC_PSTN_Set_Comm_Feature(controller_ID, + setup_packet, data, size); + break; + case GET_LINE_CODING : + status = USB_Class_CDC_PSTN_Get_Line_Coding(controller_ID, + setup_packet, data, size); + break; + case SET_LINE_CODING : + status = USB_Class_CDC_PSTN_Set_Line_Coding(controller_ID, + setup_packet, data, size); + break; + case SET_CONTROL_LINE_STATE : + status = USB_Class_CDC_PSTN_Set_Ctrl_Line_State(controller_ID, + setup_packet, data, size); + break; + case SEND_BREAK : + status = USB_Class_CDC_PSTN_Send_Break(controller_ID, + setup_packet, data, size); + break; + default: + *size=0; + break; + } + } + else if((setup_packet->request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_VENDOR) + { + /* vendor specific request */ + if(g_vendor_req_callback != NULL) + { + status = g_vendor_req_callback(controller_ID, setup_packet, data, + size); + } + } + return status; +} + + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Class_CDC_Init + * + * @brief The function initializes the Device and Controller layer + * + * @param controller_ID: Controller ID + * @param cdc_class_callback: CDC Class Callback + * @param vendor_req_callback: vendor specific class request callback + * @param param_callback: PSTN Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * This function initializes the CDC Class layer and layers it is dependent upon + *****************************************************************************/ +uint_8 USB_Class_CDC_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK cdc_class_callback, /* [IN] CDC Class Callback */ + USB_REQ_FUNC vendor_req_callback, /* [IN] Vendor Request Callback */ + USB_CLASS_CALLBACK pstn_callback, /* [IN] PSTN Callback */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ + uint_8 index,status = USB_OK; + USB_ENDPOINTS *usb_ep_data = + (USB_ENDPOINTS *)USB_Desc_Get_Endpoints(controller_ID); +#ifndef COMPOSITE_DEV + /* Initialize the device layer*/ + status = _usb_device_init(controller_ID, NULL, + (uint_8)(usb_ep_data->count+1), bVregEn); + /* +1 is for Control Endpoint */ + + if(status == USB_OK) + { + /* Initialize the generic class functions */ + status = USB_Class_Init(controller_ID,USB_Class_CDC_Event, + USB_Other_Requests); +#endif +#if IMPLEMENT_QUEUING + for(index = 0; index < usb_ep_data->count; index++) + { + g_cdc_ep[index].endpoint = usb_ep_data->ep[index].ep_num; + g_cdc_ep[index].type = usb_ep_data->ep[index].type; + g_cdc_ep[index].bin_consumer = 0x00; + g_cdc_ep[index].bin_producer = 0x00; + } +#endif +#if PSTN_SUBCLASS_NOTIF_SUPPORT + /* Initialize the pstn subclass functions */ + status = USB_Class_CDC_Pstn_Init(controller_ID,pstn_callback); +#endif + if(status == USB_OK) + { + /* save the callback pointer */ + g_cdc_class_callback = cdc_class_callback; + + /* save the callback pointer */ + g_vendor_req_callback = vendor_req_callback; + } +#ifndef COMPOSITE_DEV + } +#endif + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_DeInit + * + * @brief The function de-initializes the Device and Controller layer + * + * @param controller_ID : Controller ID + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + *This function de-initializes the CDC Class layer + *****************************************************************************/ +uint_8 USB_Class_CDC_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 status = USB_OK; +#ifdef COMPOSITE_DEV + UNUSED(controller_ID) +#endif + /* save the callback pointer */ + g_cdc_class_callback = NULL; + + /* free the vendor request callback pointer */ + g_vendor_req_callback = NULL; + +#ifndef COMPOSITE_DEV + /* call common class deinit function */ + status = USB_Class_DeInit(controller_ID); + + if(status == USB_OK) + /* Call device deinit function */ + status = _usb_device_deinit(); +#endif + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Send_Data + * + * @brief This function is used to send data from CDC Class over send endpoints + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param app_buff : Buffer to send + * @param size : Length of the transfer + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Helper function. Sends DATA over CIC and DIC Interfaces to Host + *****************************************************************************/ +uint_8 USB_Class_CDC_Send_Data ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8_ptr app_buff, /* Pointer to Application Buffer */ + USB_PACKET_SIZE size /* Size of Application Buffer */ +) +{ + uint_8 status = USB_OK; + +#if IMPLEMENT_QUEUING + uint_8 index; + uint_8 producer, consumer; + + USB_ENDPOINTS *usb_ep_data = (USB_ENDPOINTS *) + USB_Desc_Get_Endpoints(controller_ID); + + /* map the endpoint num to the index of the endpoint structure */ + for(index = 0; index < usb_ep_data->count; index++) + { + if(usb_ep_data->ep[index].ep_num == ep_num) + { + break; + } + } + + producer = g_cdc_ep[index].bin_producer; + consumer = g_cdc_ep[index].bin_consumer; + + if(((uint_8)(producer - consumer)) != (uint_8)(MAX_QUEUE_ELEMS)) + { + /* the bin is not full*/ + + uint_8 queue_num = (uint_8)(producer % MAX_QUEUE_ELEMS); + + /* put all send request parameters in the endpoint data structure */ + g_cdc_ep[index].queue[queue_num].controller_ID = controller_ID; + g_cdc_ep[index].queue[queue_num].channel = ep_num; + g_cdc_ep[index].queue[queue_num].app_data.data_ptr = app_buff; + g_cdc_ep[index].queue[queue_num].app_data.data_size = size; + + /* increment producer bin by 1*/ + g_cdc_ep[index].bin_producer = ++producer; + + if((uint_8)(producer - consumer) == (uint_8)1) + { +#endif + status = USB_Class_Send_Data(controller_ID, ep_num, app_buff,size); +#if IMPLEMENT_QUEUING + } + } + else /* bin is full */ + { + status = USBERR_DEVICE_BUSY; + } +#endif + return status; +} + +/* EOF */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.h new file mode 100644 index 0000000..952d141 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc.h @@ -0,0 +1,202 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack CDC class layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_CDC_H +#define _USB_CDC_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_descriptor.h" +#include "usb_class.h" +#include "usb_cdc_pstn.h" +#include "usb_devapi.h" +#ifdef COMPOSITE_DEV +#include "usb_composite.h" +#endif + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +/* Class specific request Codes */ +#define SEND_ENCAPSULATED_COMMAND (0x00) +#define GET_ENCAPSULATED_RESPONSE (0x01) +#define SET_COMM_FEATURE (0x02) +#define GET_COMM_FEATURE (0x03) +#define CLEAR_COMM_FEATURE (0x04) +#define SET_AUX_LINE_STATE (0x10) +#define SET_HOOK_STATE (0x11) +#define PULSE_SETUP (0x12) +#define SEND_PULSE (0x13) +#define SET_PULSE_TIME (0x14) +#define RING_AUX_JACK (0x15) +#define SET_LINE_CODING (0x20) +#define GET_LINE_CODING (0x21) +#define SET_CONTROL_LINE_STATE (0x22) +#define SEND_BREAK (0x23) +#define SET_RINGER_PARAMS (0x30) +#define GET_RINGER_PARAMS (0x31) +#define SET_OPERATION_PARAM (0x32) +#define GET_OPERATION_PARAM (0x33) +#define SET_LINE_PARAMS (0x34) +#define GET_LINE_PARAMS (0x35) +#define DIAL_DIGITS (0x36) +#define SET_UNIT_PARAMETER (0x37) +#define GET_UNIT_PARAMETER (0x38) +#define CLEAR_UNIT_PARAMETER (0x39) +#define GET_PROFILE (0x3A) +#define SET_ETHERNET_MULTICAST_FILTERS (0x40) +#define SET_ETHERNET_POW_PATTER_FILTER (0x41) +#define GET_ETHERNET_POW_PATTER_FILTER (0x42) +#define SET_ETHERNET_PACKET_FILTER (0x43) +#define GET_ETHERNET_STATISTIC (0x44) +#define SET_ATM_DATA_FORMAT (0x50) +#define GET_ATM_DEVICE_STATISTICS (0x51) +#define SET_ATM_DEFAULT_VC (0x52) +#define GET_ATM_VC_STATISTICS (0x53) +#define MDLM_SPECIFIC_REQUESTS_MASK (0x7F) + +/* Class Specific Notification Codes */ +#define NETWORK_CONNECTION_NOTIF (0x00) +#define RESPONSE_AVAIL_NOTIF (0x01) +#define AUX_JACK_HOOK_STATE_NOTIF (0x08) +#define RING_DETECT_NOTIF (0x09) +#define SERIAL_STATE_NOTIF (0x20) +#define CALL_STATE_CHANGE_NOTIF (0x28) +#define LINE_STATE_CHANGE_NOTIF (0x29) +#define CONNECTION_SPEED_CHANGE_NOTIF (0x2A) +#define MDLM_SPECIFIC_NOTIF_MASK (0x5F) + +/* Events to the Application */ /* 0 to 4 are reserved for class events */ +#define USB_APP_CDC_CARRIER_DEACTIVATED (0x21) +#define USB_APP_CDC_CARRIER_ACTIVATED (0x22) + +/* other macros */ +#define NOTIF_PACKET_SIZE (0x08) +#define NOTIF_REQUEST_TYPE (0xA1) + +/* macros for queuing */ +#define MAX_QUEUE_ELEMS (4) + +#if CIC_NOTIF_ELEM_SUPPORT +#define CIC_SEND_ENDPOINT CIC_NOTIF_ENDPOINT +#endif + +#if DIC_ISOCHRONOUS_SETTING + #define DIC_SEND_ENDPOINT DIC_ISO_IN_ENDPOINT + #define DIC_RECV_ENDPOINT DIC_ISO_OUT_ENDPOINT +#else + #define DIC_SEND_ENDPOINT DIC_BULK_IN_ENDPOINT + #define DIC_RECV_ENDPOINT DIC_BULK_OUT_ENDPOINT +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ +#ifndef COMPOSITE_DEV +typedef struct _app_data_struct +{ + uint_8_ptr data_ptr; /* pointer to buffer */ + USB_PACKET_SIZE data_size; /* buffer size of endpoint */ +}APP_DATA_STRUCT; +#endif + +/* structure to hold a request in the endpoint queue */ +typedef struct _usb_class_cdc_queue +{ + uint_8 controller_ID; /* Controller ID */ + uint_8 channel; /* Endpoint Number */ + APP_DATA_STRUCT app_data; /* Application Data Structure */ +}USB_CLASS_CDC_QUEUE, *PTR_USB_CLASS_CDC_QUEUE; + +/* USB class cdc endpoint data */ +typedef struct _usb_class_cdc_endpoint +{ + uint_8 endpoint; /* endpoint num */ + uint_8 type; /* type of endpoint (interrupt, bulk or isochronous) */ + uint_8 bin_consumer;/* the num of queued elements */ + uint_8 bin_producer;/* the num of de-queued elements */ + USB_CLASS_CDC_QUEUE queue[MAX_QUEUE_ELEMS]; /* queue data */ +}USB_CLASS_CDC_ENDPOINT; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Class_CDC_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK cdc_class_callback, /* [IN] CDC Class Callback */ + USB_REQ_FUNC vendor_req_callback, /* [IN] Vendor Request Callback */ + USB_CLASS_CALLBACK pstn_callback, /* [IN] PSTN Callback */ + uint_8 bVregEn /* Enables or disables internal regulator */ +); + +#ifdef COMPOSITE_DEV +extern uint_8 USB_CDC_Other_Requests(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +#endif + +extern uint_8 USB_Class_CDC_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Class_CDC_Send_Data ( + uint_8 controller_ID, + uint_8 ep_num, + uint_8_ptr buff_ptr, + USB_PACKET_SIZE size +); + +#if CIC_NOTIF_ELEM_SUPPORT +#define USB_Class_CDC_Interface_CIC_Send_Data(a,b,c) \ + USB_Class_CDC_Send_Data(a,CIC_SEND_ENDPOINT,b,c) +#endif + +#define USB_Class_CDC_Interface_DIC_Send_Data(a,b,c) \ + USB_Class_CDC_Send_Data(a,DIC_SEND_ENDPOINT,b,c) +#define USB_Class_CDC_Interface_DIC_Recv_Data(a,b,c) \ + _usb_device_recv_data(a,DIC_RECV_ENDPOINT,b,c) +#define USB_Class_CDC_Interface_DIC_Get_Send_Buffer(a,b,c) \ + _usb_device_get_send_buffer(a,DIC_SEND_ENDPOINT,b,c) + +#define USB_Class_CDC_Periodic_Task USB_Class_Periodic_Task + +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.c new file mode 100644 index 0000000..00bd791 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.c @@ -0,0 +1,409 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc_pstn.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB CDC_PSTN Sub Class implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "usb_cdc_pstn.h" /* USB CDC PSTN Sub Class Header File */ + + /***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/***************************************************************************** + * Global Functions Prototypes + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ +/* PSTN subclass callback pointer */ +static USB_CLASS_CALLBACK g_pstn_callback = NULL; +/* data terminal equipment present or not */ +static boolean g_dte_present = FALSE; +static uint_8 g_dte_status = 0; /* Status of DATA TERMINAL EQUIPMENT */ +static uint_16 g_break_duration = 0; /* Length of time in milliseconds of the + break signal */ +static uint_8 g_current_interface = 0; +static UART_BITMAP g_uart_bitmap; + +#if CIC_NOTIF_ELEM_SUPPORT +static uint_8 g_serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE] = +{ + NOTIF_REQUEST_TYPE,SERIAL_STATE_NOTIF, + 0x00,0x00,/*wValue*/ + 0x00,0x00,/*interface - modifies*/ + UART_BITMAP_SIZE,0x00,/* wlength*/ + 0x00,0x00 /*data initialized - modifies*/ +};/*uart bitmap*/ +#endif + /***************************************************************************** + * Local Functions + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_Class_CDC_Pstn_Init + * + * @brief The function initializes the PSTN Module + * + * @param controller_ID : Controller ID + * @param callback : PSTN Callback + * + * @return error + * USB_OK : Always + ****************************************************************************** + * PSTN Sub Class Initialization routine + *****************************************************************************/ +uint_8 USB_Class_CDC_Pstn_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK callback /* [IN] PSTN Callback */ +) +{ + uint_8 error = USB_OK; + UNUSED (controller_ID) + + /* save input parameters */ + g_pstn_callback = callback; + return error; +} +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Get_Line_Coding + * + * @brief This function is called in response to GetLineCoding request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data to be send + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE: When request for + * invalid Interface is presented + ****************************************************************************** + * Calls application to receive Line Coding Information + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Get_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data to be send */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + UNUSED (size) + g_current_interface = (uint_8)setup_packet->index ; + status = USB_Desc_Get_Line_Coding(controller_ID, g_current_interface, + data); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Line_Coding + * + * @brief This function is called in response to SetLineCoding request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Calls Applciation to update Line Coding Information + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + UNUSED(data) + + *size = 0; + + g_current_interface = (uint_8)setup_packet->index ; + status = USB_Desc_Set_Line_Coding(controller_ID, g_current_interface, + (uint_8_ptr *)&setup_packet); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Ctrl_Line_State + * + * @brief This function is called in response to Set Control Line State + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : Always + ****************************************************************************** + * Updates Control Line State + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Ctrl_Line_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + UNUSED(data) + *size = 0; + + g_dte_status = (uint_8)setup_packet->value ; + g_uart_bitmap._byte = 0x00; /* initialize */ + /* activate/deactivate Tx carrier */ + g_uart_bitmap.Bitmap_Uart.bTxCarrier = (g_dte_status & + CARRIER_ACTIVATION_CHECK) ? 1 : 0 ; + /* activate carrier and DTE */ + g_uart_bitmap.Bitmap_Uart.bRxCarrier = (g_dte_status & + CARRIER_ACTIVATION_CHECK) ? 1 : 0 ; + + /* Indicates to DCE if DTE is present or not */ + g_dte_present = (boolean)((g_dte_status & DTE_PRESENCE_CHECK) ? + TRUE : FALSE); + UNUSED(g_dte_present); +#if CIC_NOTIF_ELEM_SUPPORT + /* Send Notification to Host - Parameter on Device side has changed */ + USB_Class_CDC_PSTN_Send_Serial_State(controller_ID); +#endif + if(g_pstn_callback != NULL) + { +#if 1 /* original implementation */ + if(g_dte_status & CARRIER_ACTIVATION_CHECK) + { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_ACTIVATED, + NULL); + } + else + { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_DEACTIVATED, + NULL); + } +#else /* contribution from Joe Serdenkovski, see https://community.freescale.com/message/605537?et=watches.email.thread# */ + if(g_dte_status & CARRIER_ACTIVATION_CHECK) + { + if (g_dte_present) { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_ACTIVATED,NULL); + } else { + g_pstn_callback(controller_ID, USB_APP_CDC_CARRIER_DEACTIVATED,NULL); + } + } +#endif + } + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Send_Break + * + * @brief This function is called in response to Set Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : Always + ****************************************************************************** + * Updates Break Duration Information from Host + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Send_Break ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + UNUSED (controller_ID) + UNUSED (data) + *size = 0; + + g_break_duration = setup_packet->value; + UNUSED(g_break_duration); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Get_Comm_Feature + * + * @brief This function is called in response to GetCommFeature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data to be send + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Returns the status of the get comm feature request + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Get_Comm_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data to send */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ uint_8 status; + + status = USB_OK; + *size = COMM_FEATURE_DATA_SIZE; + g_current_interface = (uint_8)setup_packet->index ; + if(setup_packet->value == ABSTRACT_STATE_FEATURE) + { + status = USB_Desc_Get_Abstract_State(controller_ID, + g_current_interface, data); + } + else if(setup_packet->value == COUNTRY_SETTING_FEATURE) + { + status = USB_Desc_Get_Country_Setting(controller_ID, + g_current_interface, data); + } + else + { + *size = 0; /* for Reserved/Invalid Feature Selector Value */ + } + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Set_Comm_Feature + * + * @brief This function is called in response to SetCommFeature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Pointer to setup packet + * @param data : Pointer to Data + * @param size : Pointer to Size of Data + * + * @return status: + * USB_OK : When Successfull + * USBERR_INVALID_REQ_TYPE : When request for invalid + * Interface is presented + ****************************************************************************** + * Sets the comm feature specified by Host + *****************************************************************************/ +uint_8 USB_Class_CDC_PSTN_Set_Comm_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Pointer to setup packet */ + uint_8_ptr *data, /* [OUT] Pointer to Data */ + USB_PACKET_SIZE *size /* [OUT] Pointer to Size of Data */ +) +{ + uint_8 status; + status = USB_OK; + *size = COMM_FEATURE_DATA_SIZE; + g_current_interface = (uint_8)setup_packet->index ; + if(setup_packet->value == ABSTRACT_STATE_FEATURE) + { + status = USB_Desc_Set_Abstract_State(controller_ID, + g_current_interface, data); + } + else if(setup_packet->value == COUNTRY_SETTING_FEATURE) + { + status = USB_Desc_Set_Country_Setting(controller_ID, + g_current_interface, data); + } + else + { + *size = 0; /* for Reserved/Invalid Feature Selector Value */ + } + return status; +} + +#if CIC_NOTIF_ELEM_SUPPORT +/**************************************************************************//*! + * + * @name USB_Class_CDC_PSTN_Send_Serial_State + * + * @brief This function is called to send serial state notification + * + * @param controller_ID : Controller ID + * + * @return NONE + ****************************************************************************** + * Returns the Serial State + *****************************************************************************/ +void USB_Class_CDC_PSTN_Send_Serial_State ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + /* update array for current interface */ + g_serial_state_buf[4] = g_current_interface; + /* Lower byte of UART BITMAP */ + g_serial_state_buf[NOTIF_PACKET_SIZE+UART_BITMAP_SIZE-2] = + g_uart_bitmap._byte; + (void)USB_Class_CDC_Interface_CIC_Send_Data(controller_ID, + g_serial_state_buf, (NOTIF_PACKET_SIZE + UART_BITMAP_SIZE)); +} +#endif + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.h new file mode 100644 index 0000000..8c363d7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_cdc_pstn.h @@ -0,0 +1,127 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_cdc_pstn.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB CDC_PSTN Sub Class API header function + * + *****************************************************************************/ + +#ifndef _USB_CDC_PSTN_H +#define _USB_CDC_PSTN_H + +/****************************************************************************** + * Includes + *****************************************************************************/ + #include "usb_cdc.h" /* USB CDC Class Header File */ +/****************************************************************************** + * Constants - None + *****************************************************************************/ +#ifdef __MCF52xxx_H__ +#pragma reverse_bitfields on +#endif +typedef struct _BITMAP_UART +{ + /*lint -save -e46 field type should be _Bool, unsigned int or signed int */ + uint_8 bRxCarrier : 1; /* Receive Carrier Activation Flag */ + uint_8 bTxCarrier : 1; /* Transmit Carrier Activation Flag */ + uint_8 bBreak : 1; /* Break Flag */ + uint_8 bRingSignal : 1; /* Ring Signal Flag */ + uint_8 bFraming : 1; /* Frame Flag */ + uint_8 bParity : 1; /* Parity Flag */ + uint_8 bOverRun : 1; /* OverRun Flag */ + uint_8 reserved1 : 1; /* Reserved */ + /*lint -restore */ +}BITMAP_UART; +#ifdef __MCF52xxx_H__ +#pragma reverse_bitfields off +#endif + + +typedef union _UART_BITMAP +{ + uint_8 _byte; + BITMAP_UART Bitmap_Uart; +}UART_BITMAP; /* UART STATE BITMAP */ + + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define UART_BITMAP_SIZE (0x02) +#define ABSTRACT_STATE_FEATURE (0x01) +#define COUNTRY_SETTING_FEATURE (0x02) +#define CARRIER_ACTIVATION_CHECK (0x02) +#define DTE_PRESENCE_CHECK (0x01) + +extern uint_8 USB_Class_CDC_Pstn_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK callback +); + +extern uint_8 USB_Class_CDC_PSTN_Get_Line_Coding ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Line_Coding ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Ctrl_Line_State ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Send_Break ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Get_Comm_Feature ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Class_CDC_PSTN_Set_Comm_Feature ( + uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +#if CIC_NOTIF_ELEM_SUPPORT +extern void USB_Class_CDC_PSTN_Send_Serial_State (uint_8 controller_ID); +#endif +#endif + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.c new file mode 100644 index 0000000..f843c4b --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.c @@ -0,0 +1,493 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_class.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains USB stack Class module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_class.h" /* USB class Header File */ +#include "usb_devapi.h" /* USB device Header file */ +#include "usb_framework.h" /* USB framework module header file */ +#include "hidef.h" /* for EnableInterrupts macro */ + +#if 0 /* << EST */ +#if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) +#include "exceptions.h" +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#endif +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + /* Class callback pointer */ +static USB_CLASS_CALLBACK g_class_callback = NULL; +/* save the device state before device goes to suspend state */ +static uint_8 g_device_state_before_suspend; +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +void USB_Suspend_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Resume_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Stall_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Sof_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Reset_Service (PTR_USB_DEV_EVENT_STRUCT event ); +void USB_Error_Service (PTR_USB_DEV_EVENT_STRUCT event ); + +/***************************************************************************** + * Local Variables + *****************************************************************************/ + + /***************************************************************************** + * Local Functions - None + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#endif +/**************************************************************************//*! + * + * @name USB_Suspend_Service + * + * @brief The function is called when host suspends the USB port + * + * @param event : Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Sets the device state as USB_STATE_SUSPEND + *****************************************************************************/ +void USB_Suspend_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* Get the status of the device before suspend, so that on resume we + can get back to the same state */ + (void)_usb_device_get_status(&(event->controller_ID), + USB_STATUS_DEVICE_STATE, &g_device_state_before_suspend); + /* Set the device state in the Device Layer to SUSPEND */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + USB_STATE_SUSPEND); + + /* let the application know that bus suspend has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_SUSPEND, NULL); + + return; +} + +/**************************************************************************//*! + * + * @name USB_Resume_Service + * + * @brief The function is called when host resumes the USB port + * + * @param event : Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Restore the state of the device before suspend + *****************************************************************************/ +void USB_Resume_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_8 device_state; + (void)_usb_device_get_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + &device_state); + if(device_state == USB_STATE_SUSPEND) + { + /* + Set the device state in the Device Layer to the state + before suspend + */ + (void)_usb_device_set_status(&(event->controller_ID), + USB_STATUS_DEVICE_STATE, g_device_state_before_suspend); + } + + /* let the application know that bus resume has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_RESUME, NULL); + + return; +} + +/**************************************************************************//*! + * + * @name USB_Stall_Service + * + * @brief The function is called when endpoint is stalled + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * This function sends STALL Packet for the endpoint to be stalled. Also, sets + * the status of Endpoint as STALLED + *****************************************************************************/ +void USB_Stall_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + if(event->ep_num == CONTROL_ENDPOINT) + { + /* Update the Endpoint Status in the Device Layer to Idle */ + (void)_usb_device_set_status(&(event->controller_ID), + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (event->direction << USB_COMPONENT_DIRECTION_SHIFT)), + (uint_16)USB_STATUS_IDLE); + } + return; +} + +/**************************************************************************//*! + * + * @name USB_Sof_Service + * + * @brief The function is called when SOF flag is set (from ISR) + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * This function is called when SOF token is received by controller. Updates + * SOF Count status. + *****************************************************************************/ +void USB_Sof_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_16 sof_count; + + /* update SOF */ + sof_count = event->buffer_ptr[0]; + sof_count <<= SOF_HIGH_BYTE_SHIFT; + sof_count |= event->buffer_ptr[1]; + + /* write SOF to status */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_SOF_COUNT, + (uint_8)sof_count); + return; +} +/**************************************************************************//*! + * + * @name USB_Reset_Service + * + * @brief The function is called upon a bus reset event. + Initializes the control endpoint. + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Reset Callback function. This function re-initializes CONTROL Endpoint + *****************************************************************************/ +void USB_Reset_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + + USB_EP_STRUCT ep_struct; + uint_8 err; + + /* Initialize the endpoint 0 in both directions */ + ep_struct.direction = USB_SEND; + ep_struct.ep_num = CONTROL_ENDPOINT; + ep_struct.size = CONTROL_MAX_PACKET_SIZE; + ep_struct.type = USB_CONTROL_PIPE; + + /* Deinit Endpoint in case its already initialized */ + err = _usb_device_deinit_endpoint(&(event->controller_ID), + ep_struct.ep_num, ep_struct.direction); + /* now initialize the endpoint */ + err = _usb_device_init_endpoint(&(event->controller_ID), + ep_struct.ep_num, (uint_16)ep_struct.size, ep_struct.direction, ep_struct.type, TRUE); + + ep_struct.direction = USB_RECV; + /* Deinit Endpoint in case its already initialized */ + (void)_usb_device_deinit_endpoint(&(event->controller_ID), + ep_struct.ep_num, ep_struct.direction); + /* now initialize the endpoint */ + (void)_usb_device_init_endpoint(&(event->controller_ID), + ep_struct.ep_num, (uint_16)ep_struct.size, ep_struct.direction, ep_struct.type, TRUE); + + /* set the default device state */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + USB_STATE_DEFAULT); + + /* set the default device state */ + (void)_usb_device_set_status(&(event->controller_ID), USB_STATUS_DEVICE, + SELF_POWERED >> SELF_POWER_BIT_SHIFT); + + /* set the EndPoint Status as Idle in the device layer */ + (void)_usb_device_set_status(&(event->controller_ID), + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (USB_SEND << USB_COMPONENT_DIRECTION_SHIFT)), + USB_STATUS_IDLE); + /* let the application know that bus reset has taken place */ + g_class_callback(event->controller_ID, USB_APP_BUS_RESET, NULL); + + UNUSED(err); + return; +} + +/**************************************************************************//*! + * + * @name USB_Error_Service + * + * @brief The function is called when an error has been detected + * + * @param event: Pointer to USB Event Structure + * + * @return None + ****************************************************************************** + * Calls application with the error code received from the lower layer + *****************************************************************************/ +void USB_Error_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* notify the application of the error */ + g_class_callback(event->controller_ID, USB_APP_ERROR, + (uint_8*)(&(event->errors))); + return; +} + + +/**************************************************************************//*! + * + * @name USB_Class_Init + * + * @brief The function initializes the Class Module + * + * @param controller_ID : Controller ID + * @param class_callback : Class callback + * @param other_req_callback : Other Requests Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Initializes USB Class Module + *****************************************************************************/ +uint_8 USB_Class_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK class_callback, /* [IN] Class Callback */ + USB_REQ_FUNC other_req_callback /* [IN] Other Requests Callback */ +) +{ + uint_8 status = USB_Framework_Init(controller_ID,class_callback, + other_req_callback); + + /* save callback address */ + g_class_callback = class_callback; + + if(status == USB_OK) + { + /* Register all the services here */ + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_BUS_RESET, USB_Reset_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_SOF,USB_Sof_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_SLEEP,USB_Suspend_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_RESUME,USB_Resume_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_STALL,USB_Stall_Service); + status |= _usb_device_register_service(controller_ID, + USB_SERVICE_ERROR,USB_Error_Service); + + /* set the device state as powered */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE,USB_STATE_POWERED); + g_device_state_before_suspend = USB_STATE_POWERED; + } + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_DeInit + * + * @brief The function De-initializes the Class Module + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * De-initializes USB Class Module + *****************************************************************************/ +uint_8 USB_Class_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 status = USB_OK; + /* Free class_callback */ + g_class_callback = NULL; + + /* Unegister all the services here */ + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_BUS_RESET); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_SOF); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_SLEEP); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_RESUME); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_STALL); + status |= _usb_device_unregister_service(&controller_ID,USB_SERVICE_ERROR); + + if(status == USB_OK) + /* Call Framework deinit function */ + status = USB_Framework_DeInit(controller_ID); + + return status; +} + +/**************************************************************************//*! + * + * @name USB_Class_Initiate_Resume + * + * @brief The function initiates resume procedure + * + * @param controller_ID : Controller ID + * + * @return device_state + ******************************************************************************/ +uint_8 USB_Class_Initiate_Resume( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 device_state, state; + + (void)_usb_device_get_status(&controller_ID, USB_STATUS_DEVICE_STATE, + &device_state); + (void)_usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &state); + if((device_state == USB_STATE_SUSPEND) && + (state & REMOTE_WAKEUP_STATUS_MASK ) && + (USB_Frame_Remote_Wakeup(controller_ID) == TRUE)) + { + DisableInterrupts; +#if 0 + #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) + usb_int_dis(); + #endif +#else /* << EST */ + /* device is Kinetis K22FN120 << EST */ +#endif + /* Resume the bus */ + _usb_device_assert_resume(&controller_ID); + + device_state = USB_STATE_CONFIG; + /* Set the device state in the Device Layer to DEFAULT */ + (void)_usb_device_set_status(&controller_ID, USB_STATUS_DEVICE_STATE, + USB_STATE_CONFIG); + EnableInterrupts; + #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H) + usb_int_en(); + #endif + } + return device_state; +} + +/**************************************************************************//*! + * + * @name USB_Class_Send_Data + * + * @brief The function calls the device to send data upon receiving an IN token + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param buff_ptr : Buffer to send + * @param size : Length of transfer + * + * @return status + * USB_OK : When Successfull + * Others : Errors + ****************************************************************************** + * Used by Application to send Data on USB Bus if not suspended + *****************************************************************************/ +uint_8 USB_Class_Send_Data ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8_ptr buff_ptr, /* [IN] Buffer to send */ + USB_PACKET_SIZE size /* [IN] Length of the transfer */ +) +{ + + uint_8 status = USB_OK; + uint_8 device_state; + + device_state = USB_Class_Initiate_Resume(controller_ID); + + if(device_state != USB_STATE_SUSPEND) + { /* if not suspended */ + status = _usb_device_send_data(&controller_ID, ep_num, buff_ptr, size); + } + + return status; + } + +/**************************************************************************//*! + * + * @name USB_Class_Periodic_Task + * + * @brief The function calls for periodic tasks + * + * @param None + * + * @return None + ****************************************************************************** + * Called to check for any pending requests + *****************************************************************************/ +void USB_Class_Periodic_Task (void) +{ +#ifdef DELAYED_PROCESSING + USB_Framework_Periodic_Task(); +#endif +} + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.h new file mode 100644 index 0000000..6d377ab --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_class.h @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_class.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB stack class layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_CLASS_H +#define _USB_CLASS_H + + +/*#define DELAYED_PROCESSING 1 This define is used to delay the control + processing and not have it executed as part + of the interrupt routine */ +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define SOF_HIGH_BYTE_SHIFT (8) +#define GET_STATUS_DEVICE_MASK (0x0003) +#ifdef OTG_BUILD +#define GET_STATUS_OTG_MASK (0x0001) +#endif +#define REMOTE_WAKEUP_STATUS_MASK (0x0002) +#define BUS_POWERED (0x80) +#define SELF_POWERED (0x40) +#define SELF_POWER_BIT_SHIFT (6) + +/* Events to the Application */ +#define USB_APP_BUS_RESET (0) +#define USB_APP_CONFIG_CHANGED (1) +#define USB_APP_ENUM_COMPLETE (2) +#define USB_APP_SEND_COMPLETE (3) +#define USB_APP_DATA_RECEIVED (4) +#define USB_APP_ERROR (5) +#define USB_APP_GET_DATA_BUFF (6) +#define USB_APP_EP_STALLED (7) +#define USB_APP_EP_UNSTALLED (8) +#define USB_APP_GET_TRANSFER_SIZE (9) +#define USB_APP_BUS_SUSPEND (0x0A) +#define USB_APP_BUS_RESUME (0x0B) + +/* max packet size for the control endpoint */ + +/* USB Specs define CONTROL_MAX_PACKET_SIZE for High Speed device as only 64, + whereas for FS its allowed to be 8, 16, 32 or 64 */ + +#if HIGH_SPEED_DEVICE +#define CONTROL_MAX_PACKET_SIZE (64) /* max supported value is 64*/ +#else +#define CONTROL_MAX_PACKET_SIZE (16) /* max supported value is 16*/ +#endif + +/* identification values and masks to identify request types */ +#define USB_REQUEST_CLASS_MASK (0x60) +#define USB_REQUEST_CLASS_STRD (0x00) +#define USB_REQUEST_CLASS_CLASS (0x20) +#define USB_REQUEST_CLASS_VENDOR (0x40) + +/****************************************************************************** + * Types + *****************************************************************************/ +/* eight byte usb setup packet structure */ +typedef struct _USB_SETUP_STRUCT { + uint_8 request_type; /* bmRequestType */ + uint_8 request; /* Request code */ + uint_16 value; /* wValue */ + uint_16 index; /* wIndex */ + uint_16 length; /* Length of the data */ +} USB_SETUP_STRUCT; + +/* callback function pointer structure for Application to handle events */ +typedef void(_CODE_PTR_ USB_CLASS_CALLBACK)(uint_8, uint_8, void*); + +/* callback function pointer structure to handle USB framework request */ +typedef uint_8 (_CODE_PTR_ USB_REQ_FUNC)(uint_8, USB_SETUP_STRUCT *, + uint_8_ptr*, + USB_PACKET_SIZE*); + +/*callback function pointer structure for application to provide class params*/ +typedef uint_8 (_CODE_PTR_ USB_CLASS_SPECIFIC_HANDLER_FUNC)( + uint_8, + uint_16, + uint_16, // Application needs to know which Interface is being communicated with + uint_8_ptr*, + USB_PACKET_SIZE*); + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Class_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK class_callback, + USB_REQ_FUNC other_req_callback +); + +extern uint_8 USB_Class_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Class_Initiate_Resume( + uint_8 controller_ID +); + +extern uint_8 USB_Class_Send_Data ( + uint_8 controller_ID, + uint_8 ep_num, + uint_8_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern void USB_Class_Periodic_Task(void); + +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.c new file mode 100644 index 0000000..8a63c67 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.c @@ -0,0 +1,2954 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2012 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dci_kinetis.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains Kinetis USB stack controller layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include +#include "usb_dciapi.h" /* USB DCI API Header File */ +#include "usb_devapi.h" /* USB Device API Header File */ +#include "usb_dci_kinetis.h" /* USB DCI Header File */ +#include "usb_bdt_kinetis.h" /* USB BDT Structure Header File */ +#include "wdt_kinetis.h" +#include "usb_class.h" + +/***************************************************************************** + * Constant and Macro's - None + *****************************************************************************/ +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef USE_FEEDBACK_ENDPOINT + extern uint_32 feedback_data; + extern uint_32 gNrSamples; +#endif + +/* location for BDT Table and buff */ +#if (defined(__CWCC__)||defined(__GNUC__)) + __attribute__((__aligned__(512))) +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma data_alignment = 512 +#endif + +#if !HIGH_SPEED_DEVICE + #if defined __CC_ARM + __align(512) uint_8 g_Mem[BYTES_1024]; + #else +#if 0 + static uint_8 g_Mem[BYTES_1024]; +#else + uint_8 g_Mem[BYTES_1024]; +#endif + #endif + /* Pointer to BDT Map Structure */ + BDTMAP *g_bdtmap = NULL; + /* per endpoint per direction bdt index structure */ + static BDT_ELEM g_bdt_elem[MAX_BDT_INDEX >> 1]; +#endif +/* stores Controller ID */ +static uint_8 g_dci_controller_Id = 0; +#if HIGH_SPEED_DEVICE +static uint_8 g_dci_address_state = 0; +#endif /* HIGH_SPEED_DEVICE */ + +#if !HIGH_SPEED_DEVICE +/* Start BDT buffer Address */ +static uint_32 g_bdt_address; +#endif /* HIGH_SPEED_DEVICE */ +/* Transfer direction */ +static uint_8 g_trf_direction = USB_TRF_UNKNOWN; + + +// HIGH_SPEED_DEVICE +#if HIGH_SPEED_DEVICE + #define MAX_DTDS_PER_EP 5 // maximum number of transfer descriptors + #define DTD_FREE 0 + #define DTD_BUSY 1 + #define MAX_ENDPOINT_NUMBER 4 + + // QH structures are 64-byte aligned + #define TOTAL_QHD_SIZE (SIZE_OF_QHD * (MAX_ENDPOINT_NUMBER * 2)) + // TD structures are 64-byte aligned + #define TOTAL_QTD_SIZE ((SIZE_OF_DTD0) * (MAX_ENDPOINT_NUMBER * 2) * MAX_DTDS_PER_EP) + + #ifdef __CWCC__ + #pragma define_section usb_dqh ".usb_dqh" RW + __declspec(usb_dqh) uint_8 g_usbd_qh_buf[TOTAL_QHD_SIZE]; // 512 + #pragma define_section usb_dtd ".usb_dtd" RW + __declspec(usb_dtd) uint_8 g_usbd_td_buf[TOTAL_QTD_SIZE]; // 1280 + #else + #pragma data_alignment=(0x1000) + uint_8 g_usbd_qh_buf[TOTAL_QHD_SIZE]; // 512 + #pragma data_alignment=(0x800) + uint_8 g_usbd_td_buf[TOTAL_QTD_SIZE]; // 1280 + #endif + + + /* flag status for td */ + static struct _td_status + { + uint_8 status; // DTD_BUSY or DTD_FREE + unsigned int total_bytes; // Original total bytes to transfer (not used by EP0) + volatile struct dtd_setup_t *phys_td; // Pointer to physical TD (not used by EP0) + } g_usbd_td_flag[MAX_ENDPOINT_NUMBER * 2][MAX_DTDS_PER_EP]; + static struct dtd_setup_t *g_usbd_qh_tail[MAX_ENDPOINT_NUMBER * 2]; +#endif // HIGH_SPEED_DEVICE + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +static void USB_Bus_Reset_Handler(void); +#if !HIGH_SPEED_DEVICE +static uint_8 USB_DCI_Get_BDT_Index(uint_8 ep_num, + uint_8 direction, + boolean odd); +static uint_8 USB_DCI_Validate_Param(uint_8 ep_num, + uint_8 direction, + boolean odd); +#ifdef LONG_SEND_TRANSACTION +static void USB_DCI_Prepare_Send_Data(P_BUFF_DSC buffer_dsc, + P_BDT_ELEM bdt_elem); +#endif /* LONG_SEND_TRANSACTION */ +static void USB_Bus_Token_Cpl_Handler(uint_8 stat, + USB_DEV_EVENT_STRUCT* event); +#endif /* HIGH_SPEED_DEVICE */ + +// HIGH_SPEED_DEVICE +#if HIGH_SPEED_DEVICE +static uint_8 K70_ULPI_SetDeviceMode(uint_8 controller_ID); +static void usbd_ep_qh_init(uint_8 controller_ID, + unsigned char endpt_number, unsigned char direction, + unsigned int max_pkt_len, + unsigned int zlt, unsigned char mult, uint_32 next_dtd); +static void usbd_setup_qhead(struct dqh_t *qhead); +static void usbd_setup_td(struct dtd_t *td); +static unsigned int usbd_get_dqh(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction); +static void usbd_ep_setup(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned char ep_type); +static void usbd_ep_complete_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_setup_packet_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_read_setup_packet(uint_8 controller_ID, unsigned char *setup_packet); +static void usbd_port_change( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +); +static void usbd_ep0_complete(USB_DEV_EVENT_STRUCT* event); +static void usbd_dtd_complete(USB_DEV_EVENT_STRUCT* event); +static usb_status_t usbd_receive_data_ep0out(uint_8 controller_ID, unsigned int ep0_data_buffer, unsigned int sz); +static usb_status_t usbd_receive_data_epxout(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz); +static void usbd_add_td(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td); +static void usbd_prime_ep(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td); +static usb_status_t usbd_send_data_epxin(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz); +static usb_status_t usbd_send_data_ep0in(uint_8 controller_ID, + unsigned int ep0_data_buffer, unsigned int sz, + unsigned char zlt_enable); + +#endif +#ifdef USB_LOWPOWERMODE + static void Enter_StopMode(STOP_MODE stop_mode); +#endif +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_Bus_Reset_Handler + * + * @brief The function handles Bus Reset Interrupt + * + * @param None + * + * @return None + * + ****************************************************************************** + * This functions is called when USB Bus Reset event is received on USB Bus. + * This function clears all the errors conditions and reinit Global data + * structures. Also resets USB device controller. + *****************************************************************************/ +static void USB_Bus_Reset_Handler (void) +{ +#if !HIGH_SPEED_DEVICE + USB0_ERRSTAT = ERR_STAT_CLEAR_ALL; /* clear USB error flag */ + USB0_CTL |= USB_CTL_ODDRST_MASK; /* Reset to Even buffer */ + USB0_ADDR = 0; /* reset to default address */ + /* Select System Clock and Disable Weak Pull Downs */ + USB0_USBCTRL = 0x00; + + /* Clear bdt elem structure */ + Clear_Mem((uint_8_ptr)(g_bdt_elem), + (sizeof(BDT_ELEM) * (MAX_BDT_INDEX >> 1)), + (uint_8)UNINITIALISED_VAL); + + /* Clear Memory for BDT and buffer Data */ + Clear_Mem((uint_8_ptr)g_bdtmap,(uint_32) BYTES_1024, (uint_8)0); + + /* Initialize BDT buffer address */ + g_bdt_address = ((uint_32)g_bdtmap + BYTES_512); + + g_trf_direction = USB_TRF_UNKNOWN; + + USB0_CTL &= ~USB_CTL_ODDRST_MASK; + USB0_USBTRC0 |= 0x40; /* attach CFv1 core to USB bus */ + + USB0_ERREN = ERR_ENB_ENABLE_ALL; /* Enable All Error Interrupts */ + USB0_INTEN = INTENB_BUS_RESET_VAL; /* Enable All Interrupts except RESUME */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + +#else + uint_32 reg; + + //Clear the device address + USBHS_DEVICEADDR &= ~USBHS_DEVICEADDR_USBADR_MASK; + + // 1. Clear all setup token semaphores + reg = USBHS_EPSETUPSR; + USBHS_EPSETUPSR = reg; + + // 2. Clear all the endpoint complete status bits + reg = USBHS_EPCOMPLETE; + USBHS_EPCOMPLETE = reg; + + // 3. Cancel all primed status + while(USBHS_EPPRIME); + USBHS_EPFLUSH = 0xffffffff; + + // 4. If reset bit is not cleared at this point force reset device + if(!(USBHS_PORTSC1 & USBHS_PORTSC1_PR_MASK)){ + USBHS_USBCMD |= USBHS_USBCMD_RST_MASK; + } + + // 5. Free(reset) all allocated dTDs + memset(g_usbd_td_buf, 0, TOTAL_QTD_SIZE); + memset(g_usbd_td_flag, + 0, + MAX_ENDPOINT_NUMBER * 2 * MAX_DTDS_PER_EP * sizeof(g_usbd_td_flag)/sizeof(*g_usbd_td_flag) + ); + + g_trf_direction = USB_TRF_UNKNOWN; + UNUSED(g_trf_direction); +#endif +} + +#if !HIGH_SPEED_DEVICE +/**************************************************************************//*! + * + * @name USB_DCI_Get_BDT_Index + * + * @brief The function maps endpoint number and direction to bdt index + * + * @param ep_num : Endpoint Number + * @param direction: Endpoint direction + * @param odd : Odd or even buffer + * + * @return bdt index : Mapped bdt index + * INVALID_BDT_INDEX : In case of error + * + ****************************************************************************** + * This function returns BDT Index from Endpoint number, direction, + * odd/even buffer + *****************************************************************************/ +static uint_8 USB_DCI_Get_BDT_Index ( + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8 direction, /* [IN] Endpoint direction */ + boolean odd /* [IN] Odd or even buffer */ +) +{ + uint_8 bdt_index = INVALID_BDT_INDEX; + + if(ep_num < MAX_SUPPORTED_ENDPOINTS) + { + /* per endpoint 4 bdt_index -- 2 for recv 2 for send */ + bdt_index=(uint_8)((ep_num * 4) + (uint_8)odd); + + if(direction == USB_SEND) + { + bdt_index += 2; + } + } + return bdt_index; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Validate_Param + * + * @brief The function validates endpoint number & direction parameters + * and returns bdt index. + * + * @param ep_num : Endpoint Number + * @param direction: Endpoint direction + * @param odd : odd or even buffer + * + * @return bdt index : mapped bdt index + * INVALID_BDT_INDEX : incase of error + * + ****************************************************************************** + * This function validates endpoint parameters and returns bdt index + *****************************************************************************/ +static uint_8 USB_DCI_Validate_Param ( + uint_8 ep_num, /* [IN] Endpoint Number */ + uint_8 direction, /* [IN] Endpoint direction */ + boolean odd /* [IN] Odd or even buffer */ +) +{ + /* Get bdt index mapped to endpoint number-direction and odd/even buffer */ + uint_8 bdt_index = USB_DCI_Get_BDT_Index(ep_num, direction, odd); + + if((bdt_index != INVALID_BDT_INDEX) && + (g_bdt_elem[TRANSFER_INDEX(bdt_index)].len == + (uint_16)UNINITIALISED_VAL)) + { + /* Incase length in bdt_elem is uninitialised return invalid index */ + bdt_index = INVALID_BDT_INDEX; + } + return bdt_index; +} +#endif /* HIGH_SPEED_DEVICE */ + +#ifdef LONG_SEND_TRANSACTION +#if !HIGH_SPEED_DEVICE +/**************************************************************************//*! + * + * @name USB_DCI_Prepare_Send_Data + * + * @brief The function sets up the BDT for Send + * + * @param buffer_dsc : Pointer to buffer descriptor element in USB_RAM + * @param bdt_elem : Pointer to per endpoint/direction structure + * + * @return None + * + ****************************************************************************** + * This functions configures Buffer Descriptor (Address and Count) + *****************************************************************************/ +static void USB_DCI_Prepare_Send_Data ( + P_BUFF_DSC buffer_dsc, /* [OUT] Pointer to buffer descriptor + element in USB_RAM */ + P_BDT_ELEM bdt_elem /* [IN] Pointer to per endpoint/direction + structure */ +) +{ + uint_8_ptr buff_ptr = bdt_elem->app_buffer + bdt_elem->curr_offset; + uint_16 current_count = 0; + + /* adjust size based on the input at the init endpoint */ + if((bdt_elem->app_len - bdt_elem->curr_offset) > bdt_elem->len) + { + /* If size of packet is greater than endpoint buffer size */ + current_count = bdt_elem->len; + } + else + { + /* If size of packet is smaller than endpoint buffer size */ + current_count = (uint_16)(bdt_elem->app_len - bdt_elem->curr_offset); + } + + buffer_dsc->cnt = SWAP16(current_count); + + buffer_dsc->addr = SWAP32((uint_32)buff_ptr); +} +#endif /* HIGH_SPEED_DEVICE */ +#endif /* LONG_SEND_TRANSACTION */ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + +/**************************************************************************//*! + * + * @name USB_DCI_Init + * + * @brief The function initializes the Controller layer + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : Always + ****************************************************************************** + * Initializes the USB controller + *****************************************************************************/ +uint_8 USB_DCI_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ +#if !HIGH_SPEED_DEVICE +#if USB_USER_CONFIG_USE_STACK_INIT + /* Select System Clock and Disable Weak Pull Downs */ + USB0_USBCTRL = 0x00; +#endif + + /* save the controller_ID for future use */ + g_dci_controller_Id = controller_ID; + + /* Clear bdt elem structure */ + Clear_Mem((uint_8_ptr)(g_bdt_elem), + (sizeof(BDT_ELEM) * (MAX_BDT_INDEX >> 1)), + (uint_8)UNINITIALISED_VAL); + g_bdtmap = (BDTMAP *)((uint_32)g_Mem); + + /* Clear Memory for BDT and buffer Data */ + Clear_Mem((uint_8_ptr)g_bdtmap,(uint_32) BYTES_1024, (uint_8)0); + + #ifndef OTG_BUILD + #if 1 /* hardware bug workaround */ /* << EST: need to keep this workaround for FRDM-KL25Z */ + /* Hard Reset to the USB Module */ + USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + + /* loop till the Reset bit clears */ + while((USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK)) + { + }; + #if !USB_USER_CONFIG_USE_STACK_INIT + { + /* need to re-init USB, as the hard reset above has reset the whole module! */ + void USB0_Init(void); /* prototype */ + USB0_Init(); /* call Processor Expert Init_USB_OTG Init() */ + } + #endif + + #endif + #endif + + g_trf_direction = USB_TRF_UNKNOWN; + +#if USB_USER_CONFIG_USE_STACK_INIT + /* Asynchronous Resume Interrupt Enable */ + USB0_USBTRC0 |= 0x40; /* undocumented bit???? */ +#endif + if(bVregEn) + { + SIM_SOPT1 |= SIM_SOPT1_USBREGEN_MASK; // enable usb voltage regulator + } + else + { + SIM_SOPT1 &= ~SIM_SOPT1_USBREGEN_MASK; // disable usb voltage regulator + } + + /* Set the BDT Table address, Need to be on 512 byte boundary */ + /* D8 Bit is masked in BDT_PAGE_01 */ + USB0_BDTPAGE1 = (uint_8)(((uint_32)g_bdtmap >> 8)& 0xFE); + USB0_BDTPAGE2 = (uint_8)((uint_32)g_bdtmap >> 16); + USB0_BDTPAGE3 = (uint_8)((uint_32)g_bdtmap >> 24); + + /* Initialized BDT buffer address */ + g_bdt_address = ((uint_32)g_bdtmap + BYTES_512); + +#if USB_USER_CONFIG_USE_STACK_INIT + #ifndef OTG_BUILD + /* Pull Up configuration */ + USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK; + #endif +#endif + USB0_CTL = USB_CTL_USBENSOFEN_MASK; /* Enable USB module */ + USB0_ISTAT = INT_STAT_CLEAR_ALL; /* Clear USB interrupts*/ + + /* Remove suspend state */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + +#if USB_USER_CONFIG_USE_STACK_INIT + /* Enable USB RESET Interrupt */ + USB0_INTEN |= USB_INTEN_USBRSTEN_MASK; + + /* Enable USB Sleep Interrupt */ + USB0_INTEN |= USB_INTEN_SLEEPEN_MASK; + + USB0_OTGCTL = USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK; +#endif /* USB_USER_CONFIG_USE_STACK_INIT */ +#else // HIGH_SPEED_DEVICE + /* save the controller_ID for future use */ + g_dci_controller_Id = controller_ID; + memset(g_usbd_qh_buf, 0, TOTAL_QHD_SIZE); + memset(g_usbd_td_buf, 0, TOTAL_QTD_SIZE); + + // initialize module in device mode + uint_8 status; + status = K70_ULPI_SetDeviceMode(controller_ID); + if (status != USB_OK) + return status; + + // initialize endpoint 0 + usbd_ep_qh_init(controller_ID, EP0, IN, 64, 0, 0, 1); + usbd_ep_qh_init(controller_ID, EP0, OUT, 64, 0, 0, 1); + + // setup interrupts + USBHS_USBINTR = USBHS_USBINTR_UE_MASK // USB interrupt + | USBHS_USBINTR_UEE_MASK // USB error + | USBHS_USBINTR_PCE_MASK // Port change + | USBHS_USBINTR_URE_MASK // Reset enable + | USBHS_USBINTR_SRE_MASK // SOF received + | USBHS_USBINTR_SLE_MASK // suspend received + | USBHS_USBINTR_SEE_MASK; // System error + + // enable pullup on DP and initiate attach event + USBHS_USBCMD |= USBHS_USBCMD_RS_MASK; +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_DeInit + * + * @brief The function de-initializes the Controller layer + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : Always + ****************************************************************************** + * Initializes the USB controller + *****************************************************************************/ +uint_8 USB_DCI_DeInit(void) +{ +#if !HIGH_SPEED_DEVICE + +#ifdef MCU_MK70F12 +#if 0 /* hardware bug workaround */ + // Reset module + USB0_USBTRC0 |= USB_USBTRC0_USBRESET_MASK; + + // Wait for reset to complete + while((USB0_USBTRC0 & USB_USBTRC0_USBRESET_MASK)); +#endif + +#else + /* Detach CFv1 core to USB bus*/ + USB0_USBTRC0 &= ~0x40; +#endif + + + /* Clear USB interrupts*/ + USB0_ISTAT = INT_STAT_CLEAR_ALL; + + /* Disable USB RESET Interrupt */ + USB0_INTEN &= ~USB_INTEN_USBRSTEN_MASK; + + /* Disable USB module */ + USB0_CTL &= ~USB_CTL_USBENSOFEN_MASK; + + USB0_OTGCTL &= ~(USB_OTGCTL_DPHIGH_MASK | USB_OTGCTL_OTGEN_MASK); +#else // HIGH_SPEED_DEVICE + +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Init_EndPoint + * + * @brief The function initializes an endpoint + * + * @param controller_ID : Controller ID + * @param ep_ptr : Pointer to EndPoint Structures + * @param flag : Zero Termination + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_INIT_FAILED : When Error + ****************************************************************************** + * + * This function initializes an endpoint and the Bufffer Descriptor Table + * entry associated with it. Incase the input parameters are invalid it will + * return USBERR_EP_INIT_FAILED error. + * + *****************************************************************************/ +uint_8 USB_DCI_Init_EndPoint ( + uint_8 controller_ID,/* [IN] Controller ID */ + USB_EP_STRUCT_PTR ep_ptr, /* [IN] Pointer to Endpoint structure, + (endpoint number, + endpoint type, + endpoint direction, + max packet size) */ + boolean flag /* [IN] Zero Termination */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_8 bdtmap_index; + uint_8 bdtelem_index; + uint_8 ep_num = ep_ptr->ep_num; + uint_8 direction = ep_ptr->direction; + uint_32 ep_ctrl[2] = {EP_OUT, EP_IN}; + P_BUFF_DSC temp; + P_BDT_ELEM bdt_elem; + UNUSED(controller_ID); + + /* if the max packet size is greater than the max buffer size */ + if(ep_ptr->size > MAX_EP_BUFFER_SIZE) + { + ep_ptr->size = MAX_EP_BUFFER_SIZE; + } + + /* Get the bdt index correspoding to the endpoint */ + bdtmap_index = USB_DCI_Get_BDT_Index(ep_num, direction, + USB_RAM_EVEN_BUFFER); + bdtelem_index = (uint_8)TRANSFER_INDEX(bdtmap_index); + + /* + incase the bdtmap_index is invalid + or already initialised return with an error + */ + if((bdtmap_index == INVALID_BDT_INDEX) || + (g_bdt_elem[bdtelem_index].len != (uint_16)UNINITIALISED_VAL) || + (ep_ptr->type > USB_INTERRUPT_PIPE) || + (ep_ptr->direction > USB_SEND)) + { + return USBERR_EP_INIT_FAILED; + } + + bdt_elem = &g_bdt_elem[bdtelem_index]; + /* Reset Handler resets bdtmap_index to UNINITIALISED_VAL */ + if(bdt_elem->bdtmap_index == (uint_8)UNINITIALISED_VAL) + { + bdt_elem->bdtmap_index = 0; + } + + /* update bdt element structure */ + bdt_elem->len = (uint_16)ep_ptr->size; + bdt_elem->flag = flag; + /* preserving even/odd buffer bit */ + bdt_elem->bdtmap_index &= 0x01; + bdt_elem->bdtmap_index |= ((direction << 1) | (ep_num << 2)); + bdt_elem->addr = g_bdt_address; + bdt_elem->type = ep_ptr->type; + bdt_elem->direction = direction; + + temp = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + + /* Update BDTMAP for endpoint's EVEN Buffer */ + temp->cnt = SWAP16((uint_16)ep_ptr->size); + temp->addr = SWAP32(g_bdt_address); + temp->Stat._byte = (_CPU | _DATA0 | _DTS); + + /* Update BDTMAP for endpoint's ODD Buffer */ + temp = &g_bdtmap->ep_dsc[(uint8_t)((bdt_elem->bdtmap_index) ^ 1)]; + + temp->cnt = SWAP16((uint_16)ep_ptr->size); + temp->addr = SWAP32(g_bdt_address); + temp->Stat._byte = (_CPU | _DATA1 | _DTS); + + /* update the buffer address for the next endpoint */ + g_bdt_address += ep_ptr->size; + + if(direction == USB_RECV) + { + /* + For Recv Endpoints + Give SIE Control to DATA0 + */ + temp = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + temp->Stat._byte |= _SIE; + } + + /* enable handshake for Non-Isochronous Endpoints */ + ep_ctrl[direction] |= ((ep_ptr->type != USB_ISOCHRONOUS_PIPE) ? + HSHK_EN:0x00); + /* set the EndPoint Control MCU Register*/ + *((&USB0_ENDPT0) + (4 * ep_num)) |= ep_ctrl[direction]; +#else /* HIGH_SPEED_DEVICE */ + unsigned char mult; + + /* No need to initialize EP0 */ + if (ep_ptr->ep_num == CONTROL_ENDPOINT) + return USB_OK; + + switch (ep_ptr->type & 0x3) { + case EP_TRANSFER_TYPE_CONTROL: + case EP_TRANSFER_TYPE_BULK: + case EP_TRANSFER_TYPE_INTERRUPT: + mult = 0; + break; + case EP_TRANSFER_TYPE_ISOCHRONOUS: + /* Calculate the ISO transfer High-Bandwidth Pipe Multiplier + * The ISO endpoints, must set Mult 1, 2, 3 for high speed + * and only 1 for full speed + */ +#ifdef ULPI_FORCE_FULLSPEED + mult = 1; +#else + mult = (unsigned char)(1 + (((ep_ptr->size) >> 11) & 0x03)); +#endif + } + + /* setup dQH */ + usbd_ep_qh_init(controller_ID, ep_ptr->ep_num, ep_ptr->direction, ep_ptr->size, flag, mult, 0xDEAD0001); + + /* enable endpoint */ + usbd_ep_setup(controller_ID, ep_ptr->ep_num, ep_ptr->direction, ep_ptr->type); +#endif /* HIGH_SPEED_DEVICE */ + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Cancel_Transfer + * + * @brief The function cancels any pending Transfers which ahve not been sent + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USBERR_NOT_SUPPORTED : Always + ****************************************************************************** + * This function just returns Error Code not supported + *****************************************************************************/ +uint_8 USB_DCI_Cancel_Transfer ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ +#if !HIGH_SPEED_DEVICE +#ifdef LONG_TRANSACTION + uint_8 status= USBERR_UNKNOWN_ERROR; + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + uint_8 bdtelem_index = (uint_8)TRANSFER_INDEX(bdt_index); + UNUSED(handle); + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + P_BDT_ELEM bdt_elem = &g_bdt_elem[bdtelem_index]; + P_BUFF_DSC buffer_dsc = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index]; + P_BUFF_DSC buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_elem->bdtmap_index ^ 1]; + /* Clear SIE Control Bit for both buffers*/ + buffer_dsc->Stat._byte &= ~_SIE; + buffer_dsc_alt->Stat._byte &= ~_SIE; + bdt_elem->app_len = (USB_PACKET_SIZE)UNINITIALISED_VAL; + + status = USB_OK; + } + return status; +#else + return USBERR_NOT_SUPPORTED; +#endif +#else // HIGH_SPEED_DEVICE +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif + return USBERR_NOT_SUPPORTED; +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Deinit_EndPoint + * + * @brief The function de initializes an endpoint + * + * @param controller_ID : Controller ID + * @param ep_num : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USB_OK : When successfull + * USBERR_EP_DEINIT_FAILED : When unsuccessfull + ****************************************************************************** + * + * This function un-intializes the endpoint by clearing the corresponding + * endpoint control register and then clearing the bdt elem. + * + *****************************************************************************/ +uint_8 USB_DCI_Deinit_EndPoint ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (ep_num, direction, + USB_RAM_EVEN_BUFFER); + uint_8 bdtelem_index = (uint_8)TRANSFER_INDEX(bdt_index); + + /* in case the bdt_index is invalid*/ + if(bdt_index == INVALID_BDT_INDEX) + { + return USBERR_EP_DEINIT_FAILED; + } + USB_DCI_Cancel_Transfer(&controller_ID, ep_num, direction); + /* delete buffer space for both even and odd buffers */ + g_bdt_address -= (g_bdt_elem[bdtelem_index].len); + + /* Disable endpoint */ + *((&USB0_ENDPT0) + (4 * ep_num)) = EP_DISABLE; + + /* un-initialize the bdt_elem structure for this endpoint */ + g_bdt_elem[bdtelem_index].len = (uint_16)UNINITIALISED_VAL; + g_bdt_elem[bdtelem_index].addr = (uint_32)UNINITIALISED_VAL; +#else // HIGH SPEED + uint_32 reg; + + if(ep_num<1) + return USB_INVALID; + + // clear qhd + dqh_setup_t *dqh_word = (dqh_setup_t*)usbd_get_dqh(controller_ID, ep_num, direction); + memset((void *)dqh_word, 0, SIZE_OF_QHD); + + // clear endpoint register + reg = USBHS_EPCR(ep_num-1); + USBHS_EPCR(ep_num-1) &= ~reg; + + // flush endpoint Tx(IN) buffer + if(direction) + USBHS_EPFLUSH |= USBHS_EPFLUSH_FETB(ep_num-1); + // flush endpoint Rx(OUT) buffer + else + USBHS_EPFLUSH |= USBHS_EPFLUSH_FERB(ep_num-1); +#endif + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Stall_EndPoint + * + * @brief The function stalls an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function stalls the endpoint by setting Endpoint BDT + *****************************************************************************/ +void USB_DCI_Stall_EndPoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number to stall */ + uint_8 direction /* [IN] Direction to stall */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + bdt_index = bdt_elem->bdtmap_index; + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + (void)USB_DCI_Cancel_Transfer(handle, endpoint_number, direction); + + /* Stall endpoint */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte |= (_SIE | _BDTSTALL); + } +#else // HIGH SPEED + // check if it is control endpoint + if(endpoint_number == 0){ + // stall both directions + USBHS_EPCR0 |= USBHS_EPCR0_TXS_MASK|USBHS_EPCR0_RXS_MASK; + }else{ + + USBHS_EPCR(endpoint_number-1) |= direction?USBHS_EPCR0_TXS_MASK:USBHS_EPCR0_RXS_MASK; + } +#endif + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Unstall_EndPoint + * + * @brief The function unstalls an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function unstalls the endpoint by clearing Endpoint Control Register + * and BDT + *****************************************************************************/ +void USB_DCI_Unstall_EndPoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number to unstall */ + uint_8 direction /* [IN] Direction to unstall */ +) +{ +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + bdt_index = bdt_elem->bdtmap_index; + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + ENDPT0STR *endpoint = (ENDPT0STR*)(&USB0_ENDPT0 + (4 * endpoint_number)); + + /* Enable ENDPTx for non control endpoints */ + /* For Control Endpoint the default Value 0x0D */ + if(endpoint_number != CONTROL_ENDPOINT) + { + uint_8 endpt; + /* Enable handshaking for non isochronous endpoint */ + endpt = (uint_8)((bdt_elem->type != USB_ISOCHRONOUS_PIPE) ? + HSHK_EN:0); + /* + Enable the endpoint in the specified direction and disable + control tranfers (valid only in case the endpoint is + bidirectional) + */ + endpt |= (uint_8)(EP_CTL_DIS | + ((direction == USB_SEND)?EP_IN:EP_OUT)); + endpoint->Byte |= endpt; + } + /* Clear Endpoint Stall bit is endpoint control register */ + endpoint->Bits.EP_STALL = 0; + + /* Unstall endpoint by clearing stall bit in BDT */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte &= ~(_SIE | _BDTSTALL); + /* We Require DATA0 PID to be zero on unstall */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte = _DATA0; + if(direction == USB_RECV) + { + /* Initiate Next receive Transfer */ + USB_DCI_Recv_Data(handle, endpoint_number, NULL, 0); + } + } +#else + // todo: + // This function unstalls the endpoint by clearing Endpoint Control Register + // and QH + if(endpoint_number == 0){ + // unstall both directions + USBHS_EPCR0 &= ~(direction ? USBHS_EPCR0_TXS_MASK:USBHS_EPCR0_RXS_MASK); + }else{ + USBHS_EPCR(endpoint_number-1) &= ~(direction?USBHS_EPCR_TXS_MASK:USBHS_EPCR_RXS_MASK); + } +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif +#endif + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Get_Setup_Data + * + * @brief The function copies Setup Packet from USB RAM to application buffer + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * + * @return None + * + ****************************************************************************** + * Copies setup packet from USB RAM to Application Buffer + *****************************************************************************/ +void USB_DCI_Get_Setup_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number for the transaction */ + uint_8_ptr buffer_ptr /* [IN] Pointer to the buffer into which to read data */ +) +{ + +#if !HIGH_SPEED_DEVICE + uint_8_ptr addr; + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_RECV, + USB_RAM_EVEN_BUFFER); + + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + UNUSED(handle); + bdt_index = bdt_elem->bdtmap_index; + + /* address correponding to the endpoint */ + addr = (uint_8_ptr)SWAP32(g_bdtmap->ep_dsc[bdt_index].addr); + + /* copy bdt buffer to application buffer */ + (void)memcpy(buffer_ptr, addr, USB_SETUP_PKT_SIZE); + return; +#else // HIGH SPEED +#if USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Get_Transfer_Status + * + * @brief The function retrieves the Transfer status of an endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USBERR_TR_FAILED : When unsuccessful + * USB_STATUS_IDLE : No transfer on endpoint + * USB_STATUS_DISABLED : endpoint is disabled + * USB_STATUS_STALLED : endpoint is stalled + * USB_STATUS_TRANSFER_IN_PROGRESS : When SIE has control of BDT + ****************************************************************************** + * + * This function retrieves the transfer status of the endpoint by checking the + * BDT as well as the endpoint control register + * + *****************************************************************************/ +uint_8 USB_DCI_Get_Transfer_Status ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ + uint_8 status = USB_STATUS_DISABLED; + +#if !HIGH_SPEED_DEVICE + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, direction, + USB_RAM_EVEN_BUFFER); + UNUSED(handle); + + /* Check for valid bdt index */ + if(bdt_index != INVALID_BDT_INDEX) + { + uint_8 ep_control = (uint_8)(*((&USB0_ENDPT0)+4*endpoint_number)); + + status = USB_STATUS_IDLE; + + /* Check for direction in endpoint control register */ + if((ep_control & (EP_IN|EP_OUT)) == EP_DISABLE) + { + status = USB_STATUS_DISABLED; + } + /* Check for stall bit in endpoint control register */ + else if ((ep_control & EPCTL_STALL) == EPCTL_STALL) + { + status = USB_STATUS_STALLED ; + } + /* Check whether SIE has control of BDT */ + else if ((g_bdtmap->ep_dsc[bdt_index].Stat.SieCtlBit.own == 1) + || (g_bdtmap->ep_dsc[bdt_index ^ 1].Stat.SieCtlBit.own == 1)) + { + status = USB_STATUS_TRANSFER_IN_PROGRESS; + } + } +#else +#if USART_DEBUG + printf("%s, ep_num is %d\n", __func__, endpoint_number); +#endif /* USART_DEBUG */ + status = USB_OK; +#endif /* HIGH_SPEED_DEVICE */ + return status; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Clear_DATA0_Endpoint + * + * @brief The function clear the DATA0/1 bit + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return None + * + ****************************************************************************** + * This function clear the DATA0/1 bit + *****************************************************************************/ +void USB_DCI_Clear_DATA0_Endpoint ( + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Endpoint direction */ +) +{ + +#if !HIGH_SPEED_DEVICE + + uint_8 bdt_index = USB_DCI_Validate_Param(endpoint_number, direction, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + bdt_index = bdt_elem->bdtmap_index; + + /*Check for a valid bdt index */ + if (bdt_index != INVALID_BDT_INDEX) + { + //ENDPT0STR *endpoint = (ENDPT0STR*)(&USB0_ENDPT0 + (4 * endpoint_number)); /* << EST not used */ + g_bdtmap->ep_dsc[bdt_index].Stat._byte = _DATA0; + } + return; +#else // HIGH SPEED +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Recv_Data + * + * @brief The function retrieves data received on an RECV endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * @param size : Size of the buffer + * + * @return status + * USB_OK : When successful + * USBERR_RX_FAILED : When unsuccessful + ****************************************************************************** + * This function retrieves data received data on a RECV endpoint by copying it + * from USB RAM to application buffer + *****************************************************************************/ +uint_8 USB_DCI_Recv_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number for the transaction */ + uchar_ptr buffer_ptr, /* [OUT] Pointer to the buffer into which to receive data */ + uint_32 size /* [IN] Number of bytes to receive */ +) +{ + uint_8 status = USBERR_RX_FAILED; +#if !HIGH_SPEED_DEVICE + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_RECV, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + UNUSED(handle); + + /* For selecting even/odd buffer */ + bdt_index = bdt_elem->bdtmap_index; + + if(bdt_index != INVALID_BDT_INDEX) + { + P_BUFF_DSC buffer_dsc = &g_bdtmap->ep_dsc[bdt_index ^ 1]; + P_BUFF_DSC buffer_dsc_alt = NULL; + + /* Check for valid bdt index */ + if(bdt_elem->len != (uint_16)UNINITIALISED_VAL) + { + /* Does MCU owns it */ + if(buffer_dsc->Stat.SieCtlBit.own == FALSE) + { + if(size == 0) + { + /* + Give control to the other buffer to recv the next + packet + */ + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt->cnt = SWAP16(bdt_elem->len); + buffer_dsc_alt->addr = SWAP32(bdt_elem->addr); + + /* Give the ownership to SIE and TOGGLE DATA BIT */ + buffer_dsc_alt->Stat._byte = (uint_8)( + (buffer_dsc_alt->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + return USB_OK; + } + /* adjust size based on the input at the init endpoint */ +#ifdef LONG_RECEIVE_TRANSACTION + /* Initialise transfer */ + bdt_elem->app_len = size; + bdt_elem->app_buffer = buffer_ptr; +#endif + if(size > bdt_elem->len) + { + size = bdt_elem->len; + } + +#ifdef LONG_RECEIVE_TRANSACTION + bdt_elem->curr_offset = 0; +#endif + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt->cnt = SWAP16(size); + buffer_dsc_alt->addr = SWAP32((uint_32)buffer_ptr); + buffer_dsc_alt->Stat._byte = (uint_8)( + (buffer_dsc_alt->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + status = USB_OK; + } + } + } + return status; +#else + if (endpoint_number != 0) + { + status = usbd_receive_data_epxout(0, (unsigned int)buffer_ptr, endpoint_number, size); + } + else + status = usbd_receive_data_ep0out(0, (unsigned int)buffer_ptr, size); + + if (status != USB_SUCCESS) + { + return USBERR_RX_FAILED; + } + else + { + return USB_OK; + } +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Send_Data + * + * @brief The function configures Controller to send data on an SEND endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param buffer_ptr : Application buffer pointer + * @param size : Size of the buffer + * + * @return status + * USB_OK : When successfull + * USBERR_TX_FAILED : When unsuccessfull + ****************************************************************************** + * This function configures Controller to send data on a SEND endpoint by + * setting the BDT to send data. + *****************************************************************************/ +uint_8 USB_DCI_Send_Data ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uchar_ptr buffer_ptr, /* [IN] Application buffer pointer */ + uint_32 size /* [IN] Size of the buffer */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_8 status = USBERR_TX_FAILED; + P_BUFF_DSC buffer_dsc; + + /* validate params and get the bdt index */ + uint_8 bdt_index = USB_DCI_Validate_Param (endpoint_number, USB_SEND, USB_RAM_EVEN_BUFFER); + P_BDT_ELEM bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + UNUSED(handle); + + if(bdt_index == INVALID_BDT_INDEX) + return USBERR_TX_FAILED; + + /* Send Data After Toggling Buffer */ + bdt_index = (uint_8)bdt_elem->bdtmap_index; + + buffer_dsc = &g_bdtmap->ep_dsc[bdt_index]; + + /* Does MCU owns it and it is not stalled */ + if(!((buffer_dsc->Stat.SieCtlBit.own) ||/* For MCU: own is 0 */ + (*(&USB0_ENDPT0 + (endpoint_number * 4)) & ENDPT_EP_STALL_MASK))) + { + /* Now configure buffer_dsc->addr and buffer_dsc->cnt */ +#ifdef LONG_SEND_TRANSACTION + /* Initialize transfer */ + bdt_elem->app_len = size; + bdt_elem->app_buffer = buffer_ptr; + bdt_elem->curr_offset = 0; + + /* Prepare for send */ + USB_DCI_Prepare_Send_Data(buffer_dsc, bdt_elem); +#else + buffer_dsc->addr = SWAP32(buffer_ptr); + + /* Adjust size based on the input at the init endpoint */ + if((uint_16)size > bdt_elem->len) + { + buffer_dsc->cnt = SWAP16(bdt_elem->len); + } + else + { + buffer_dsc->cnt = SWAP16((uint_16)size); + } +#endif + if(endpoint_number == CONTROL_ENDPOINT) + { + /* Set up the control endpoint bdt for next packet */ + buffer_dsc->Stat._byte = (_SIE | _DATA1 | _DTS); + } + else + { + buffer_dsc->Stat._byte = (uint_8)( + (buffer_dsc->Stat.McuCtlBit.data << 6) | + _SIE | _DTS); + } + + status = USB_OK; + } /* Does MCU own IN BDT */ + return status; +#else // HIGH SPEED + usb_status_t status; + + if (endpoint_number != 0) { + status = usbd_send_data_epxin(0, (unsigned int)buffer_ptr, endpoint_number, size); + } + + /* Send descriptor - Data Phase */ + //zlt is false=>not zero length packet, send dev descriptor to host. + else + status = usbd_send_data_ep0in(0, (unsigned int)buffer_ptr, size, 0); + + if (status != USB_SUCCESS) + return USBERR_TX_FAILED; + + return USB_OK; +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Set_Address + * + * @brief The function configures Controller to send data on an SEND endpoint + * + * @param handle : USB Device handle + * @param address : Controller Address + * + * @return None + * + ****************************************************************************** + * Assigns the Address to the Controller + *****************************************************************************/ +void USB_DCI_Set_Address ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 address /* [IN] Address of the USB device */ +) +{ + + UNUSED(handle); + + /* set the address */ +#if !HIGH_SPEED_DEVICE + USB0_ADDR = address; +#else + USBHS_DEVICEADDR = USBHS_DEVICEADDR_USBADR(address); +#endif + + _usb_device_set_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + USB_STATE_ADDRESS); + return; +} + +/**************************************************************************//*! + * + * @name USB_DCI_Shutdown + * + * @brief The function shuts down the controller + * + * @param handle : USB Device handle + * + * @return None + * + ****************************************************************************** + * Resets USB Device Controller + *****************************************************************************/ +void USB_DCI_Shutdown ( + _usb_device_handle handle /* [IN] USB Device handle */ +) +{ + UNUSED(handle); +#if !HIGH_SPEED_DEVICE + /* Reset the Control Register */ + USB0_CTL = 0; + /* Initiate Reset in the USB Control0 Register */ + #ifndef OTG_BUILD + + USB0_USBTRC0 = _USBRESET; + #endif + + _usb_device_set_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + USB_STATE_UNKNOWN); + return; +#else +#if USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_DCI_Assert_Resume + * + * @brief The function makes the Controller start USB RESUME signaling + * + * @param handle : USB Device handle + * + * @return None + * + ****************************************************************************** + * + * This function starts RESUME signalling and then stops it after some delay. + * In this delay make sure that COP is reset. + * + *****************************************************************************/ +void USB_DCI_Assert_Resume ( + _usb_device_handle handle /* [IN] USB Device handle */ +) +{ +#if !HIGH_SPEED_DEVICE + uint_16 delay_count; + + /* Clear SUSP Bit from USB_CTRL */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + + (void)handle; + + /* Reset Low Power RESUME enable */ + USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + + USB_DCI_WAKEUP + + USB0_CTL |= USB_CTL_RESUME_MASK; /* Start RESUME signaling and make SUSPEND bit 0*/ + + delay_count = ASSERT_RESUME_DELAY_COUNT; /* Set RESUME line for 1-15 ms*/ + + do + { + delay_count--; + Watchdog_Reset(); /* Reset the COP */ + }while(delay_count); + + USB0_CTL &= ~USB_CTL_RESUME_MASK; /* Stop RESUME signalling */ + + return; +#else +#ifdef USART_DEBUG + printf("%s\n", __func__); +#endif /* USART_DEBUG */ +#endif +} + +/**************************************************************************//*! + * + * @name USB_Bus_Token_Cpl_Handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param stat : BDT stat byte + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +#if !HIGH_SPEED_DEVICE +void USB_Bus_Token_Cpl_Handler ( + uint_8 stat, /* [IN] Value of STAT register */ + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + uint_8 bdt_index = 0 ; + P_BUFF_DSC buffer_dsc = NULL; + P_BUFF_DSC buffer_dsc_alt = NULL;/* stores data of alternate buffer */ + P_BDT_ELEM bdt_elem = NULL; + boolean odd = (boolean)((stat & 0x04) >> 2); + + /* Get the direction from STAT register */ + event->direction = (uint_8)((stat & ENDPOINT_DIRECTION_MASK) >> + ENDPOINT_DIRECTION_SHIFT); + + + /* Get bdt index corresponding to endpoint number and direction */ + bdt_index = USB_DCI_Get_BDT_Index(event->ep_num,event->direction, odd); + + buffer_dsc = &g_bdtmap->ep_dsc[bdt_index]; + buffer_dsc_alt = &g_bdtmap->ep_dsc[bdt_index ^ 1]; + + bdt_elem = &g_bdt_elem[TRANSFER_INDEX(bdt_index)]; + + /* Get address from BDT */ + event->buffer_ptr = (uint_8_ptr)SWAP32(buffer_dsc->addr); + + /* Get len from BDT */ + event->len = SWAP16(buffer_dsc->cnt); + + /* Prepare for Next USB Transaction */ + bdt_index = (uint_8)(bdt_elem->bdtmap_index ^ 1); + bdt_elem->bdtmap_index = bdt_index; + + /* Toggle Data PID*/ + buffer_dsc_alt->Stat._byte = (uint_8)((buffer_dsc->Stat.McuCtlBit.data ^ 1) << 6); + + if(event->direction == USB_SEND) + { + if(event->ep_num == CONTROL_ENDPOINT) + { + /* for Control Endpoint */ + /* For Transfer Direction Host to Device */ + if(g_trf_direction == USB_RECV) + { + /* + Enters here for first time after Set_Address TRANSFER + Completed + */ + /* make Transfer Direction UNKNOWN */ + g_trf_direction = USB_TRF_UNKNOWN; + /* Cancel any pending Transfers on RECV Control Endpoint*/ + USB_DCI_Cancel_Transfer(&(event->controller_ID), (uint_8)CONTROL_ENDPOINT, + (uint_8)USB_RECV); + /* We Require DATA0 PID for Setup Token */ + buffer_dsc_alt->Stat._byte = _DATA0; + /* Prepare for Next SETUP PACKET Receive */ + USB_DCI_Recv_Data(&(event->controller_ID), + CONTROL_ENDPOINT, + NULL,0); + + } + }/* ep_num is CONTROL ENDPOINT */ + +#ifdef LONG_SEND_TRANSACTION + if( (g_trf_direction == USB_SEND) || + (event->ep_num != CONTROL_ENDPOINT) ) + { + /* update the request */ + bdt_elem->curr_offset += event->len; + /* + Initiate next USB SEND if: + 1. More Data is still pending OR + 2. Send Data == Endpoint Size AND + 3. Zero Termination Flag is TRUE + */ + if((bdt_elem->app_len > bdt_elem->curr_offset) || + (((uint_8)event->len == bdt_elem->len) && (bdt_elem->flag == TRUE)) + ) + { + /* send next Req */ + USB_DCI_Prepare_Send_Data(buffer_dsc_alt, bdt_elem); + + /* give the ownership to SIE and TOGGLE DATA BIT */ + buffer_dsc_alt->Stat._byte = (uint_8)( + ((buffer_dsc_alt->Stat.McuCtlBit.data) << 6) | + _SIE | _DTS);; + return; + } + else + { + event->buffer_ptr = bdt_elem->app_buffer; + event->len = bdt_elem->curr_offset; + } + } +#endif + }/* End of SEND loop */ + else /* direction IS USB_RECV */ + { + if(event->ep_num == CONTROL_ENDPOINT) + { + /* for Control Endpoint */ + if(buffer_dsc->Stat.RecPid.pid == USB_SETUP_TOKEN) + { + /* set setup phase */ + event->setup = TRUE; + /* Transfer direction of next packet */ + g_trf_direction = (uint_8)((uint_8) + (event->buffer_ptr[0]) >> 7); + } + else if(g_trf_direction == USB_SEND) + { + /* make Transfer Direction UNKNOWN */ + g_trf_direction = USB_TRF_UNKNOWN; + /* Cancel any pending Transfers on SEND Control Endpoint*/ + USB_DCI_Cancel_Transfer(&(event->controller_ID), (uint_8)CONTROL_ENDPOINT, + (uint_8)USB_SEND); + /* We Require DATA0 PID for Setup Token */ + buffer_dsc_alt->Stat._byte = _DATA0; + /* Prepare for Next SETUP PACKET Receive */ + USB_DCI_Recv_Data(&(event->controller_ID), + CONTROL_ENDPOINT, + NULL,0); + } + } /* ep_num is CONTROL ENDPOINT */ + +#ifdef LONG_RECEIVE_TRANSACTION + /* For NON CONTROL ENDPOINT only */ + if(bdt_elem->app_len != (USB_PACKET_SIZE)UNINITIALISED_VAL) + { + /* on control endpoint the data is only 8 bytes */ + USB_PACKET_SIZE size = event->len; + bdt_elem->curr_offset += size; + + /* + Initiate next USB RECV if: + 1. More Data is still pending OR + 2. Received Data == Endpoint Size AND + 3. Zero Termination Flag is TRUE + */ + if( + ( (size == bdt_elem->len) && + (bdt_elem->app_len > bdt_elem->curr_offset) + ) || + ( (bdt_elem->app_len)&& + (!(bdt_elem->app_len % bdt_elem->len)) && + (bdt_elem->flag == TRUE) + ) + ) + { + /* send next IO */ + uint_16 count; + count = (uint_16)(((bdt_elem->app_len - bdt_elem->curr_offset) + > bdt_elem->len) ? bdt_elem->len : + (bdt_elem->app_len - bdt_elem->curr_offset)); + if(count == 0) + { + /* For Zero byte Packet Receive */ + buffer_dsc_alt->addr = SWAP32(bdt_elem->addr); + buffer_dsc_alt->cnt = 0; + } + else + { + buffer_dsc_alt->addr = SWAP32((uint_32)(bdt_elem->app_buffer + bdt_elem->curr_offset)); + buffer_dsc_alt->cnt = SWAP16(count); + } + + /* give the ownership to SIE and Toggle DATA bit*/ + buffer_dsc_alt->Stat._byte = (uint_8)(( + (buffer_dsc_alt->Stat.McuCtlBit.data) << 6) | + _SIE | _DTS); + return; + } + else /* request completed */ + { + /* populate buffer structure */ + event->buffer_ptr = bdt_elem->app_buffer; + event->len = bdt_elem->curr_offset; + bdt_elem->app_len = (USB_PACKET_SIZE)UNINITIALISED_VAL; + } + } +#endif + } /* End of RECV loop */ + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); + + return; +} +#endif // HIGH_SPEED_DEVICE + +#if HIGH_SPEED_DEVICE +/**************************************************************************//*! + * */ +uint_32 sof_counter = 0; +static uint_32 micro_sof_counter = 0; +void USBHS_ISR(void){ + uint_32 usbsts; + uint_32 reg; + USB_DEV_EVENT_STRUCT event; + + // get interrupt status + reg = USBHS_USBINTR; + usbsts = USBHS_USBSTS & reg; + + // clear interrupt status + USBHS_USBSTS |= usbsts; + + // initialize event structure + event.controller_ID = g_dci_controller_Id; + event.setup = FALSE; + event.buffer_ptr = NULL; + event.len = 0; + event.direction = USB_RECV; + event.errors = NO_ERRORS; + event.ep_num = (uint_8)UNINITIALISED_VAL; + + // handle SOF + if(usbsts & USBHS_USBSTS_SRI_MASK){ + //USBHS_USBSTS |= USBHS_USBSTS_SRI_MASK; +#ifdef ULPI_FORCE_FULLSPEED + sof_counter++; +#else + if (++micro_sof_counter == 8){ + //sof_counter++; + //micro_sof_counter = 0; + } +#endif + } + + // handle Suspend + if (usbsts & USBHS_USBSTS_SLI_MASK){ + USB_Device_Call_Service(USB_SERVICE_SUSPEND, &event); + return; + } + + // handle Bus Reset + if (usbsts & USBHS_USBSTS_URI_MASK){ + // handle reset + USB_Bus_Reset_Handler(); + + // notify device layer + USB_Device_Call_Service(USB_SERVICE_BUS_RESET, &event); + return; + } + + // handle Transaction Complete + if (usbsts & USBHS_USBSTS_UI_MASK){ + if (!USBHS_EPSETUPSR && !USBHS_EPCOMPLETE){ +#ifdef USART_DEBUG + printf("Warning: unexpected UI interrupt\n"); +#endif /* USART_DEBUG */ + } + + // Handle dTD complete interrupt. + // Must process EP complete events first, because setup complete events + // trigger stack to re-prime endpoints. + if(USBHS_EPCOMPLETE) + usbd_ep_complete_handler(&event); + + // Handle setup compete packet interrupt + if(USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(1)) + usbd_setup_packet_handler(&event); + + // + if( (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(2))|| + (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(4))|| + (USBHS_EPSETUPSR & USBHS_EPSETUPSR_EPSETUPSTAT(8))){ +#if USART_DEBUG + printf(""); +#endif /* USART_DEBUG */ + } + } + + // handle Port Change + if (usbsts & USBHS_USBSTS_PCI_MASK){ + usbd_port_change(&event); + } + + // handle USB Error + if (usbsts & USBHS_USBSTS_UEI_MASK){ +#ifdef USART_DEBUG + printf("USBHS: Error\n"); +#endif + // Notify Device Layer of ERROR Event to error service + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + } + + // handle USB System Error + if (usbsts & USBHS_USBSTS_SEI_MASK){ +#ifdef USART_DEBUG + printf("USBHS: System Error\n"); +#endif + // Notify Device Layer of ERROR Event to error service + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + } + +} +#endif // HIGH_SPEED_DEVICE + +/**************************************************************************//*! + * + * @name USB_ISR + * + * @brief The function handles USB interrupts on the bus. + * + * @param None + * + * @return None + * + ****************************************************************************** + * This function is hooked onto interrupt 69 and handles the USB interrupts. + * After handling the interrupt it calls the Device Layer to notify it about + * the event. + *****************************************************************************/ +#if !HIGH_SPEED_DEVICE +void USB_ISR(void) +{ + /* Which interrupt occured and also was enabled */ + uint_8 v1 = USB0_ISTAT; + uint_8 v2 = USB0_INTEN; + uint_8 intr_stat = (uint_8)(v1 & v2); + uint_8 stat = (uint_8)USB0_STAT; + USB_DEV_EVENT_STRUCT event; + uint_8 dev_state = USB_STATUS_UNKNOWN; + + /* initialize event structure */ + event.controller_ID = g_dci_controller_Id; + event.setup = FALSE; + event.buffer_ptr = NULL; + event.len = 0; + event.direction = USB_RECV; + event.errors = NO_ERRORS; + + event.ep_num = (uint_8)UNINITIALISED_VAL; + + /* Get the device state from the Device Layer */ + (void)_usb_device_get_status(&g_dci_controller_Id, USB_STATUS_DEVICE_STATE, + &dev_state); + + /* if current device state is SUSPEND and Low Power Resume Flag set */ + if((USB0_USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) && (dev_state == USB_STATE_SUSPEND)) + { + /* Clear SUSP Bit from USB_CTRL */ + USB0_USBCTRL &= ~USB_USBCTRL_SUSP_MASK; + + /* Reset Low Power RESUME enable */ + USB0_USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK; + } + + /* SOF received */ + if(SOF_TOKEN_FLAG(intr_stat)) + { + uint_16 sof_count; + uint_16 tmp1, tmp2, tmp3; + tmp1 = USB0_FRMNUMH; + tmp2 = FRAME_HIGH_BYTE_SHIFT; + tmp3 = USB0_FRMNUML; + /* Clear SOF Interrupt */ + USB0_ISTAT = USB_ISTAT_SOFTOK_MASK; + sof_count = (uint_16)((tmp1 << tmp2) | tmp3); + /*address of Lower byte of Frame number*/ + event.buffer_ptr = (uint_8_ptr)(&sof_count); + /* Notify Device Layer of SOF Event */ + (void)USB_Device_Call_Service(USB_SERVICE_SOF, &event); + +#ifdef USE_FEEDBACK_ENDPOINT + // set feedback rate info number + if(gNrSamples!=0) + feedback_data = gNrSamples; + gNrSamples = 0; +#endif + } + + if(BUS_RESET_FLAG(intr_stat)) + { + /* Clear Reset Flag */ + USB0_ISTAT = USB_ISTAT_USBRST_MASK; + + /* Handle RESET Interrupt */ + USB_Bus_Reset_Handler(); + + /* Notify Device Layer of RESET Event */ + (void)USB_Device_Call_Service(USB_SERVICE_BUS_RESET, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + + /* No need to process other interrupts */ + return; + } + + if(TOKEN_COMPL_FLAG(intr_stat)) + { + /* Clear TOKEN Interrupt */ + USB0_ISTAT = USB_ISTAT_TOKDNE_MASK; + + event.ep_num = (uint_8)((stat & ENDPOINT_NUMBER_MASK) >> + ENDPOINT_NUMBER_SHIFT); + + USB_Bus_Token_Cpl_Handler(stat, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + + if(ERROR_FLAG(intr_stat)) + { + /* Clear ERROR Interrupt */ + USB0_ISTAT = USB_ISTAT_ERROR_MASK; + + v1 = USB0_ERRSTAT; + v2 = USB0_ERREN; + event.errors = (uint_8)(v1 & v2); + + /* Notify Device Layer of ERROR Event to error service */ + (void)USB_Device_Call_Service(USB_SERVICE_ERROR, &event); + + USB0_ERRSTAT = ERR_STAT_CLEAR_ALL; /*clear all errors*/ + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + + if(SLEEP_FLAG(intr_stat)) + { + /* Clear RESUME Interrupt if Pending */ + USB0_ISTAT = USB_ISTAT_RESUME_MASK; + + /* Clear SLEEP Interrupt */ + USB0_ISTAT = USB_ISTAT_SLEEP_MASK; + + /* Notify Device Layer of SLEEP Event */ + (void)USB_Device_Call_Service(USB_SERVICE_SLEEP, &event); + + /* Set Low Power RESUME enable */ + USB0_USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK; + + /* Set SUSP Bit in USB_CTRL */ + USB0_USBCTRL |= USB_USBCTRL_SUSP_MASK; + + /* Enable RESUME Interrupt */ + USB0_INTEN |= USB_INTEN_RESUMEEN_MASK; +#ifdef USB_LOWPOWERMODE + /* Enter Stop3 Mode*/ + Enter_StopMode(STOP_MODE3); +#endif + } + + if(RESUME_FLAG(intr_stat)) + { + /* Clear RESUME Interrupt */ + USB0_ISTAT = USB_ISTAT_RESUME_MASK; + + /* Notify Device Layer of RESUME Event */ + (void)USB_Device_Call_Service(USB_SERVICE_RESUME, &event); + + /* Disable RESUME Interrupt */ + USB0_INTEN &= ~USB_INTEN_RESUMEEN_MASK; + } + + if(STALL_FLAG(intr_stat)) + { + uint_8 endp_status; + event.ep_num = (uint_8)UNINITIALISED_VAL; + + /* If Control Endpoint is stalled then unstall it. + For other endpoints host issues clear endpoint feature request + to unstall them */ + + /* Get Control Endpoint Status*/ + (void)_usb_device_get_status(&(event.controller_ID), + (USB_STATUS_ENDPOINT|CONTROL_ENDPOINT), + &endp_status); + if(endp_status == USB_STATUS_STALLED) + { + event.ep_num = CONTROL_ENDPOINT; + event.direction = USB_SEND; + } + + /* Clear STALL Interrupt */ + USB0_ISTAT = USB_ISTAT_STALL_MASK; + + /* Notify Device Layer of STALL Event */ + (void)USB_Device_Call_Service(USB_SERVICE_STALL, &event); + + /* Clearing this bit allows the SIE to continue token processing + and clear suspend condition */ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; + } + return; +} +#endif // HIGH_SPEED_DEVICE + +/**************************************************************************//*! + * + * @name Clear_Mem + * + * @brief The function clears memory starting from start_addr till count bytes + * + * @param start_addr : Buffer Start address + * @param count : Count of Bytes + * @param val : Value to be set + * + * @return None + ****************************************************************************** + * This function is an implementation of memset + *****************************************************************************/ +void Clear_Mem ( + uint_8_ptr start_addr, /* [OUT] Buffer Start address */ + uint_32 count, /* [IN] Count of Bytes */ + uint_8 val /* [IN] Value to be set */ +) +{ + (void)memset(start_addr, val, count); + return; +} + +#ifdef USB_LOWPOWERMODE +/**************************************************************************//*! + * + * @name Enter_StopMode + * + * @brief The function configures STOP Mode + * + * @param stop_mode : STOP MODE to be entered + * + * @return None + ****************************************************************************** + * This function configures different STOP MODES defined by the controller. + * Used to put controller into low power mode. Only STOP MODE 3 is implemented + *****************************************************************************/ +static void Enter_StopMode(STOP_MODE stop_mode) +{ + switch(stop_mode) + { + case STOP_MODE1: + /* + We enter Default Stop Mode + */ + break; + case STOP_MODE2: + /* Save IO Pin Status in a global variable + IO Pin Status is to be restored at POR. + Check if PPDC + */ + /* Set PPDC */ + break; + case STOP_MODE3: + /* Clear PPDC */ + SPMSC2_PPDC = 0; + /* Disable Low Voltage Detect */ + SPMSC1_LVDSE = 0; + break; + case STOP_MODE4: + break; + } + /* Enter STOP Mode*/ + _Stop; +} + +#endif + + +/* HIGH_SPEED_DEVICE */ +#if HIGH_SPEED_DEVICE + +extern void delay(int delayloop); + +static uint_8 K70_ULPI_SetDeviceMode(uint_8 controller_ID){ + // device init + unsigned int count = 10000; + unsigned int reg; + + // reset usb controller + reg = USBHS_USBCMD; + reg |= USBHS_USBCMD_RST_MASK; + USBHS_USBCMD = reg; + // check if reset done, port is enabled + while (USBHS_USBCMD & USBHS_USBCMD_RST_MASK); + + // enable USB work in device mode + reg = USBHS_USBMODE; + reg &= ~0x3; + reg |= 0x2; // device mode + + // Disable Setup Lockout by writing '1' to SLOM in USBMODE + reg &= ~(USBHS_USBMODE_SDIS_MASK); + // Setup Lockouts Off + reg |= USBHS_USBMODE_SLOM_MASK; + // this register can only be written once after reset + USBHS_USBMODE = reg; + + // wait for mode to be set + while (((USBHS_USBMODE & 0x3) != 0x2) && (--count)) ; + + if (count == 0) + return USBERR_INIT_FAILED; //timeout + +#ifdef ULPI_FORCE_FULLSPEED + reg = USBHS_PORTSC1; + reg |= USBHS_PORTSC1_PFSC_MASK; + USBHS_PORTSC1 = reg; /* force full speed */ +#endif + + // Configure ENDPOINTLISTADDR Pointer + USBHS_EPLISTADDR = (unsigned int)g_usbd_qh_buf & 0xfffff800; + + // Set OTG termination, controls the pulldown on DM + reg = USBHS_OTGSC; + reg |= (0x1 << 3); + USBHS_OTGSC = reg; + + // clear the usb intr status + USBHS_USBSTS = 0xffffffff; + + return USB_OK; +} + +/*! + * Initialize the USB device endpoint queue head structure + */ +static void usbd_ep_qh_init(uint_8 controller_ID, + unsigned char endpt_number, unsigned char direction, unsigned int max_pkt_len, + unsigned int zlt, unsigned char mult, uint_32 next_dtd) +{ + struct dqh_t qhead; + unsigned int total_bytes; + + memset((void*)&qhead, 0, sizeof(qhead)); + + // Initialize device queue head in system memory + if(endpt_number == CONTROL_ENDPOINT) + total_bytes = 8; // 8 bytes for the 1st setup packet + else + total_bytes = max_pkt_len; + qhead.dqh_base = usbd_get_dqh(controller_ID, endpt_number, direction); + qhead.next_link_ptr = next_dtd; + qhead.zlt = zlt; + qhead.mps = max_pkt_len; + qhead.ios = IOS_SET; + // todo: check + qhead.terminate = TERMINATE; + qhead.total_bytes = total_bytes; + qhead.ioc = IOC_SET; + qhead.status = NO_STATUS; + qhead.mult = mult; + qhead.buffer_ptr0 = 0; + qhead.current_offset = 0; + qhead.buffer_ptr1 = 0; + qhead.buffer_ptr2 = 0; + qhead.buffer_ptr3 = 0; + qhead.buffer_ptr4 = 0; + + /* Set Device Queue Head */ + usbd_setup_qhead(&qhead); + // Initialize TD list to empty + g_usbd_qh_tail[(endpt_number * 2) + direction] = NULL; +} + +/*! + * Setup the queue head for the USB device + * + * @param qhead The queue head data structure that contains the necessary configuration data + */ +static void usbd_setup_qhead(struct dqh_t *qhead) +{ + volatile struct dqh_setup_t *dqh_word = (volatile struct dqh_setup_t *)qhead->dqh_base; + + // 0x0 + // Bit31:30 Mult; Bit29 zlt; Bit26:16 mps; Bit15 ios + dqh_word->dqh_word0 = + (((uint_32)((qhead->zlt) << 29)) | + ((uint_32)((qhead->mps) << 16)) | + (((uint_32)(qhead->ios) <<15)) | + (uint_32)((qhead->mult) << 30)); + + // 0x4 + // Current dTD Pointer => for hw use, not modified by DCD software + dqh_word->dqh_word1 = 0x0; + + // 0x8 + // Next dTD Pointer + dqh_word->dqh_word2 = (((qhead->next_link_ptr) & 0xFFFFFFE0) | qhead->terminate); + + // 0xC + // Bit30:16 total_bytes; Bit15 ioc; Bit11:10 MultO; Bit7:0 status + dqh_word->dqh_word3 = + ((((uint_32)(qhead->total_bytes) & 0x7FFF) << 16) | + ((uint_32)(qhead->ioc) << 15) | + (qhead->status)); + + // 0x10 + // Bit31:12 Buffer Pointer (Page 0) + dqh_word->dqh_word4 = + ((qhead->buffer_ptr0 & 0xFFFFF000) | + (qhead->current_offset & 0xFFF)); + + // 0x14 + // Bit31:12 Buffer Pointer (Page 1) + dqh_word->dqh_word5 = (qhead->buffer_ptr1 & 0xFFFFF000); + + // 0x18 + // Bit31:12 Buffer Pointer (Page 2) + dqh_word->dqh_word6 = (qhead->buffer_ptr2 & 0xFFFFF000); + + // 0x1C + // Bit31:12 Buffer Pointer (Page 3) + dqh_word->dqh_word7 = (qhead->buffer_ptr3 & 0xFFFFF000); + + // 0x20 + // Bit31:12 Buffer Pointer (Page 4) + dqh_word->dqh_word8 = (qhead->buffer_ptr4 & 0xFFFFF000); + + // 0x24 + // Reserved + dqh_word->dqh_word9 = 0; + + // 0x28 + // Setup Buffer 0 + dqh_word->dqh_word10 = 0; + + // 0x2C + // Setup Buffer 1 + dqh_word->dqh_word11 = 0; +} + +/*! + * Setup the transfer descriptor + * + * @param td The TD data sturcture that contains the necessary configuration data + */ +static void usbd_setup_td(struct dtd_t *td) +{ + volatile struct dtd_setup_t *dtd_word = (volatile struct dtd_setup_t *)td->dtd_base; + + /* Bit31:5 Next Link Pointer ; Bit0 terminate */ + dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate); + + /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */ + dtd_word->dtd_word1 = ((unsigned int)td->total_bytes & 0x7FFF) << 16; + dtd_word->dtd_word1 |= ((unsigned int)td->ioc << 15) | (td->status); + + /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */ + dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF)); + + /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */ + dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 2 ; */ + dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 3 ; */ + dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000); + + /* Bit31:12 Buffer Pointer Page 4 ; */ + dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000); + +} +/*! + * Get the offset of DQH from the QH buffer base + * + * @param endpt_number The end point number, start from 0 + * @param direction The In or Out endpoint + * + * @return The relative offset of DQH + * @return 0 if can't find a free DTD + */ +static unsigned int usbd_get_dqh(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction) +{ + + unsigned char *qh_buf = g_usbd_qh_buf; + + /* direction OUT = 0 and IN = 1 */ + return (unsigned int)(qh_buf + (SIZE_OF_QHD * (endpt_number * 2 + direction))); +} + +/*! + * Get the offset of DTD from the TD buffer base + * + * @param endpt_number The end point number, start from 0 + * @param direction The In or Out endpoint + * + * @return The relative offset of DTD + */ +static unsigned int usbd_get_dtd(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned int sz) +{ + /* If Maximum EPs supported in n then EPno will range from 0 to (n-1) */ + unsigned int i; + unsigned char *td_buf = g_usbd_td_buf; + + int td_index = (endpt_number * 2) + direction; + + for (i = 0; i < MAX_DTDS_PER_EP; i++) { + + if (g_usbd_td_flag[td_index][i].status == DTD_FREE || + g_usbd_td_flag[td_index][i].total_bytes == 0) { + g_usbd_td_flag[td_index][i].status = DTD_BUSY; + // printf("ep%d direction%d alloc = %d\n", endpt_number, direction, i); + g_usbd_td_flag[td_index][i].phys_td = (volatile struct dtd_setup_t *) + ((unsigned int) td_buf + + (SIZE_OF_DTD0) *(td_index) * MAX_DTDS_PER_EP + + i * (SIZE_OF_DTD0)); + g_usbd_td_flag[td_index][i].total_bytes = sz; +#if USART_DEBUG + if(endpt_number == 1){ + printf("usbd_get_dtd ep1\n"); + } + if(endpt_number == 2){ + printf("usbd_get_dtd ep2\n"); + } + if(endpt_number == 3){ + printf("usbd_get_dtd ep3\n"); + } +#endif /* USART_DEBUG */ + return (unsigned int)g_usbd_td_flag[td_index][i].phys_td ; + } + } + // todo: clear dtd and g_usbd_td_flag and point to first item +#ifdef USART_DEBUG + printf("Cannot get dTD!\n"); +#endif + return 0; +} + +static void usbd_ep_setup(uint_8 controller_ID, unsigned char endpt_number, unsigned char direction, unsigned char ep_type) +{ + if(endpt_number == CONTROL_ENDPOINT){ + return; + } + + unsigned int temp = 0; + + if (direction) { + //if (endpt_number) + temp |= USBHS_EPCR_TXR_MASK; + temp |= USBHS_EPCR_TXE_MASK; + temp |= ((unsigned int)(ep_type) << USBHS_EPCR_TXT_SHIFT); + /* configure RX endpoint as bulk(see K70 RM) */ + temp |= ((unsigned int)(2) << USBHS_EPCR_RXT_SHIFT); + } else { +// /if (endpt_number) + temp |= USBHS_EPCR_RXR_MASK; + temp |= USBHS_EPCR_RXE_MASK; + temp |= ((unsigned int)(ep_type) << USBHS_EPCR_RXT_SHIFT); + /* configure TX endpoint as bulk(see K70 RM) */ + temp |= ((unsigned int)(2) << USBHS_EPCR_TXT_SHIFT); + } + + // Initialize endpoints 1-3 + USBHS_EPCR(endpt_number-1) = temp; +} + +/**************************************************************************//*! + * + * @name usbd_setup_packet_handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +static void usbd_setup_packet_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + unsigned char setup_packet[8]; + + // Clear setup complete register + USBHS_EPSETUPSR = USBHS_EPSETUPSR; + + // Read setup packet + usbd_read_setup_packet(event->controller_ID, setup_packet); + + // Assume EP0 + event->ep_num = CONTROL_ENDPOINT; + + // Direction of setup complete is always Receive + event->direction = USB_RECV; + event->buffer_ptr = setup_packet; + event->len = sizeof(setup_packet); + event->setup = TRUE; + + /* Transfer direction of next packet */ + g_trf_direction = (uint_8)((uint_8) + (event->buffer_ptr[0]) >> 7); + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); +} + +// Read in setup packet. Assumes EP0. +static void usbd_read_setup_packet(uint_8 controller_ID, unsigned char *setup_packet) +{ + dqh_setup_t *dqh_word; + uint_32 dqh_address; + uint_32 reg; + uint_32 count = 10000; + int i; + usb_standard_device_request_t *setup_struct; + + // a. Clear setup complete register + reg = USBHS_EPSETUPSR; + USBHS_EPSETUPSR = reg; + + /* Get the Device Queue Head Address for EP0 OUT */ + dqh_address = usbd_get_dqh(controller_ID, EP0, OUT); + dqh_word = (dqh_setup_t *) dqh_address; + + do { + // b. Setup tripwire bit + USBHS_USBCMD |= USBHS_USBCMD_SUTW_MASK; + + // c. Copy the SetupBuffer into local software byte array + reg = (dqh_word->dqh_word10); + + /* This is due to the simulator bug for word variant access on EMI but actually design has word invariant access */ + for (i = 0; i < 4; i++) { + setup_packet[i] = (unsigned int)((reg >> (8 * i)) & 0xFF); + } + reg = (dqh_word->dqh_word11); + for (i = 0; i < 4; i++) { + setup_packet[i + 4] = (unsigned int)((reg >> (8 * i)) & 0xFF); + } + + //todo change to processor speed independent count + // d. Read USBCMD[SUTW] bit (if set, continue, else goto step b) + } while (!(USBHS_USBCMD & USBHS_USBCMD_SUTW_MASK) && (--count)); + + if (!count){ +#ifdef USART_DEBUG + printf("error getting setup buffer\n"); +#endif /* USART_DEBUG */ + } + + // e. Clear USBCMD[SUTW] bit + USBHS_USBCMD &= ~USBHS_USBCMD_SUTW_MASK; + + setup_struct = (usb_standard_device_request_t *)setup_packet; + if (setup_struct->bRequest == SET_ADDRESS) { + g_dci_address_state = 1; + } +} + + +static void usbd_port_change( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +){ +} + + +/**************************************************************************//*! + * + * @name usbd_dtd_handler + * + * @brief The function handles Token Complete USB interrupts on the bus. + * + * @param event : Pointer to USB EVENT Structure + * + * @return None + ****************************************************************************** + * This function handles Token Complete USB interrupts on the bus. + *****************************************************************************/ +static void usbd_ep_complete_handler( + USB_DEV_EVENT_STRUCT* event /* [IN] Pointer to USB EVENT Structure */ +) +{ + int i; + unsigned int ep_complete; + + // todo: check +#if USART_DEBUG + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(2)){ + printf("ep1: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(4)){ + printf("ep2: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ERCE(8)){ + printf("ep3: RECV\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(2)){ + printf("ep1: SEND\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(4)){ + printf("ep2: SEND\n"); + } + if(USBHS_EPCOMPLETE&USBHS_EPCOMPLETE_ETCE(8)){ + printf("ep3: SEND\n"); + } +#endif /* USART_DEBUG */ + // Get and clear endpoint complete register + ep_complete = USBHS_EPCOMPLETE; + USBHS_EPCOMPLETE = ep_complete; + + // Handle all ep bits set in ep complete register + for (i = 0; i < 16; i++) + { + // Determine bit position in ep complete register + // (skip over the reserved bits) + unsigned int ep_bit = (i < 8) ? i : (i + 8); + + if (ep_complete & (1 << ep_bit)) + { + if (ep_bit < 8) + { + // Endpoint Receive Complete Event + event->direction = USB_RECV; + event->ep_num = i; + } + else + { + // Endpoint Transmit Complete Event + event->direction = USB_SEND; + event->ep_num = ep_bit - 16; + } + + if (event->ep_num == CONTROL_ENDPOINT) + { + // Control endpoint handling + usbd_ep0_complete(event); + } + else + { + // Non-control endpoint handling + usbd_dtd_complete(event); + } + } + } +} + +// Control endpoint complete handling +static void usbd_ep0_complete(USB_DEV_EVENT_STRUCT* event) +{ + volatile struct dtd_setup_t *dtd_word; + unsigned int i; + unsigned int endpt_number = event->ep_num; + unsigned int direction = event->direction; + + // Walk the TD status array to find the next completed TD + for (i = 0; i < MAX_DTDS_PER_EP; i++) + { + unsigned int td_index = (endpt_number * 2) + direction; + + // Get dTD associated with this endpoint and direction + dtd_word = g_usbd_td_flag[td_index][i].phys_td; + + // Determine if dTD is busy (not free) and completed (not active) + if ((g_usbd_td_flag[td_index][i].status == DTD_BUSY) && ((dtd_word->dtd_word1 & 0x80) != 0x80)) + { + // Mark dTD as free + g_usbd_td_flag[td_index][i].status = DTD_FREE; + + if (g_dci_address_state ==1) { + event->ep_num = CONTROL_ENDPOINT; + event->buffer_ptr = 0; + event->len = 0; + g_dci_address_state =0; + } + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); + } + } +} + +// Handle endpoint dTD complete +static void usbd_dtd_complete(USB_DEV_EVENT_STRUCT* event) +{ + volatile struct dtd_setup_t *dtd_word; + unsigned int i; + unsigned int endpt_number = event->ep_num; + unsigned int direction = event->direction; + + // todo: check +#if USART_DEBUG + if(event->ep_num == 1){ + printf("usbd_dtd_complete ep1\n"); + } + if(event->ep_num == 2){ + printf("usbd_dtd_complete ep2\n"); + } + if(event->ep_num == 3){ + printf("usbd_dtd_complete ep3\n"); + } +#endif /*USART_DEBUG */ + // Walk the TD status array to find the next completed TD + for (i = 0; i < MAX_DTDS_PER_EP; i++) + { + unsigned int td_index = (endpt_number * 2) + direction; + + // Get dTD associated with this endpoint and direction + dtd_word = g_usbd_td_flag[td_index][i].phys_td; + + // Determine if dTD is busy (not free) and completed (not active) + if ((g_usbd_td_flag[td_index][i].status == DTD_BUSY) && ((dtd_word->dtd_word1 & 0x80) != 0x80)) + { + // Get original number of bytes to transfer + unsigned int total_bytes = g_usbd_td_flag[td_index][i].total_bytes; + // Subtract number of remaining bytes not transferred + event->len = total_bytes - (dtd_word->dtd_word1 >> 16) & 0x7FFF; + event->buffer_ptr = (uint_8 *)dtd_word->dtd_word2 - event->len; + + // Mark dTD as free + g_usbd_td_flag[td_index][i].status = DTD_FREE; + + // If this was the tail, mark list as empty + if (dtd_word == g_usbd_qh_tail[td_index]) + g_usbd_qh_tail[td_index] = NULL; + + /* Notify Device Layer of Data Received or Sent Event */ + (void)USB_Device_Call_Service(event->ep_num, event); +// break; + } + } +} + +/*! + * Receive data through EPx + * + * @param epx_data_buffer EPx receive buffer + * @param sz Number of bytes to receive + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_receive_data_epxout(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int direction = OUT; + + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, ep_num, direction, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get the total bytes to be received */ + total_bytes = sz; + +#if USART_DEBUG + if (total_bytes > 20 * 1024) + printf("Error!!! %s, size is %d\n", __func__, sz); +#endif /* USART_DEBUG */ + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = epx_data_buffer; + td.current_offset = (epx_data_buffer & 0xFFF); + td.buffer_ptr1 = (epx_data_buffer & 0xFFFFF000) + 0x1000; + td.buffer_ptr2 = (epx_data_buffer & 0xFFFFF000) + 0x2000; + td.buffer_ptr3 = (epx_data_buffer & 0xFFFFF000) + 0x3000; + td.buffer_ptr4 = (epx_data_buffer & 0xFFFFF000) + 0x4000; + + /* Set the Transfer Descriptor */ + usbd_setup_td(&td); + + // Add TD to TD list for this endpoint + direction + usbd_add_td(controller_ID, ep_num, direction, &td); + + return USB_SUCCESS; +} + +/*! + * Receive data through EP0 + * + * @param ep0_data_buffer EP0 receive buffer + * @param sz Number of bytes to receive + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_receive_data_ep0out(uint_8 controller_ID, unsigned int ep0_data_buffer, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int dqh_address; + unsigned int temp; + +// printf_info("%s, size is %d\n", __func__, sz); + + // Yi if (ep0_data_buffer != NULL) + // memset((void *)ep0_data_buffer, 0x0, 256); //todo hard-coded size + + /* Get Device Device Queue Head of the requested endpoint */ + dqh_address = usbd_get_dqh(controller_ID, EP0, OUT); + + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, EP0, OUT, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get the total bytes to be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = dtd_address + 0x20; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = ep0_data_buffer; + td.current_offset = (ep0_data_buffer & 0xFFF); + td.buffer_ptr1 = 0; + td.buffer_ptr2 = 0; + td.buffer_ptr3 = 0; + td.buffer_ptr4 = 0; + + /* Set the Transfer Descriptor */ + usbd_setup_td(&td); + + //Yi + //(*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = dtd_address; + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + /* 3. prime endpoint by writing '1' in ENDPTPRIME */ + temp = USBHS_EPPRIME; + temp |= EPOUT_PRIME; + USBHS_EPPRIME = temp; + while (USBHS_EPPRIME & EPOUT_PRIME) ; //wait prime end + + return USB_SUCCESS; +} + +// Prime endpoint +static void usbd_prime_ep(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td) +{ + unsigned int temp; + + unsigned int ep_mask = (direction == OUT ? EPOUT_PRIME : EPIN_PRIME); + // Get Device Device Queue Head of the requested endpoint + unsigned int dqh_address = usbd_get_dqh(controller_ID, ep_num, direction); + + /* Enable ZLT when data size is in multiple of Maximum Packet Size */ + /* set ZLT enable */ + if (direction == IN) + { + (*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + } + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = td->dtd_base; + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + /* 3. prime endpoint by writing '1' in ENDPTPRIME */ + temp = USBHS_EPPRIME; + temp |= ep_mask << ep_num; + USBHS_EPPRIME = temp; +} + +// Add TD to TD list and prime endpoint based on this algorithm: +// Appendix +// 5.5.3 Executing A Transfer Descriptor +// To safely add a dTD, the DCD must be follow this procedure which will handle the event where the device +// controller reaches the end of the dTD list at the same time a new dTD is being added to the end of the list. +// Determine whether the link list is empty: +// Check DCD driver to see if pipe is empty (internal representation of linked-list should indicate if any packets +// are outstanding). +// Case 1: Link list is empty +// 1. Write dQH next pointer AND dQH terminate bit to 0 as a single DWord operation. +// 2. Clear active & halt bit in dQH (in case set from a previous error). +// 3. Prime endpoint by writing '1' to correct bit position in ENDPTPRIME. +// Case 2: Link list is not empty +// 1. Add dTD to end of linked list. +// 2. Read correct prime bit in ENDPTPRIME - if '1' DONE. +// 3. Set ATDTW bit in USBCMD register to '1'. +// 4. Read correct status bit in ENDPTPRIME. (store in tmp. variable for later) [[this should be ENDPTSTATUS, not ENDPTPRIME]} +// 5. Read ATDTW bit in USBCMD register. +// If '0' goto 3. +// If '1' continue to 6. +// 6. Write ATDTW bit in USBCMD register to '0'. +// 7. If status bit read in (4) is '1' DONE. +// 8. If status bit read in (4) is '0' then Goto Case 1: Step 1. +// +static void usbd_add_td(uint_8 controller_ID, unsigned char ep_num, unsigned char direction, struct dtd_t *td) +{ + // Get the index into the TD list for this endpoint + direction + int td_index = (ep_num * 2) + direction; + + if (g_usbd_qh_tail[td_index] == NULL) + { + // Case 1: Link list is empty + + usbd_prime_ep(controller_ID, ep_num, direction, td); + } + else + { + // Case 2: Link list is not empty + + unsigned int ep_mask = (direction == OUT ? EPOUT_PRIME : EPIN_PRIME); + + // Add TD to tail next_link_ptr + // Clear Terminate bit to indicate pointer is valid + g_usbd_qh_tail[td_index]->dtd_word0 = td->dtd_base & 0xFFFFFFE0; + + // If EP is already primed, we are done + if (!(USBHS_EPPRIME & (ep_mask << ep_num))) + { + // EP not primed, check if it is active + unsigned int ep_status = 0; + unsigned int temp; + + // Use Add dTD Tripwire to properly read endpoint status register + do + { + /* write '1' to Add Tripwire (ATDTW) in USBCMD register */ + temp = USBHS_USBCMD; + temp |= (0x1 << USBHS_USBCMD_ATDTW_SHIFT); + USBHS_USBCMD = temp; + + // Read endpoint status + ep_status = USBHS_EPSR & (ep_mask << ep_num); + + } while (!USBHS_USBCMD & (0x1 << USBHS_USBCMD_ATDTW_SHIFT)); + + /* write '0' to Add Tripwire (ATDTW) in USBCMD register */ + temp = USBHS_USBCMD; + temp &= ~(0x1 << USBHS_USBCMD_ATDTW_SHIFT); + USBHS_USBCMD = temp; + + if (!ep_status) + { + // Status is inactive, so need to prime EP + usbd_prime_ep(controller_ID, ep_num, direction, td); + } + } + } + + // Make this TD the tail + g_usbd_qh_tail[td_index] = (struct dtd_setup_t *)td->dtd_base; +} + +/*! + * Send data through endpoint x + * + * @param epx_data_buffer EPx send buffer + * @param sz Number of bytes to send + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_send_data_epxin(uint_8 controller_ID, unsigned int epx_data_buffer, uint_8 ep_num, unsigned int sz) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address; + unsigned int direction = IN; + + /* verify Endpoint Number and address */ + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, ep_num, direction, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get Total Bytes to Be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = epx_data_buffer; + td.current_offset = (epx_data_buffer & 0xFFF); + td.buffer_ptr1 = (epx_data_buffer & 0xFFFFF000) + 0x1000; + td.buffer_ptr2 = (epx_data_buffer & 0xFFFFF000) + 0x2000; + td.buffer_ptr3 = (epx_data_buffer & 0xFFFFF000) + 0x3000; + td.buffer_ptr4 = (epx_data_buffer & 0xFFFFF000) + 0x4000; + + /* Set the transfer descriptor */ + usbd_setup_td(&td); + + // Add TD to TD list for this endpoint + direction + usbd_add_td(controller_ID, ep_num, direction, &td); + + return USB_SUCCESS; +} + +/*! + * Send data through endpoint 0 + * + * @param ep0_data_buffer EP0 send buffer + * @param sz Number of bytes to send + * @param zlt_enable If ZLT is enabled + * + * @return SUCCESS on success, otherwise FAIL when timeout + */ +static usb_status_t usbd_send_data_ep0in(uint_8 controller_ID, + unsigned int ep0_data_buffer, unsigned int sz, + unsigned char zlt_enable) +{ + struct dtd_t td; + unsigned int total_bytes; + unsigned int dtd_address, dqh_address; + + /* varify Endpoint Number and address */ + /* Get Device Transfer Descriptor of the requested endpoint */ + dtd_address = usbd_get_dtd(controller_ID, EP0, IN, sz); + if (!dtd_address) + { + return USB_FAILURE; + } + + /* Get Device Queue head of the requested endpoint */ + dqh_address = usbd_get_dqh(controller_ID, EP0, IN); + + /* Get Total Bytes to Be received */ + total_bytes = sz; + + td.dtd_base = dtd_address; + td.next_link_ptr = 0; + td.terminate = TERMINATE; + td.total_bytes = total_bytes; + td.ioc = IOC_SET; + td.status = ACTIVE; + td.buffer_ptr0 = ep0_data_buffer; + td.current_offset = (ep0_data_buffer & 0xFFF); + td.buffer_ptr1 = 0; + td.buffer_ptr2 = 0; + td.buffer_ptr3 = 0; + td.buffer_ptr4 = 0; + + /* Set the transfer descriptor */ + usbd_setup_td(&td); + + /* Enable ZLT when data size is in multiple of Maximum Packet Size */ + /* set ZLT enable */ + (*(volatile unsigned int *)(dqh_address)) &= ~0x20000000; + + /* 1. write dQH next ptr and dQH terminate bit to 0 */ + *(volatile unsigned int *)(dqh_address + 0x8) = (dtd_address); + + /* 2. clear active & halt bit in dQH */ + *(volatile unsigned int *)(dqh_address + 0xC) &= ~0xFF; + + USBHS_EPPRIME |= EPIN_PRIME; + + /* 4. wait for prime complete */ + while (USBHS_EPPRIME & EPIN_PRIME); + + return USB_SUCCESS; +} +#endif /* HIGH_SPEED_DEVICE */ diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.h new file mode 100644 index 0000000..a3bc696 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dci_kinetis.h @@ -0,0 +1,311 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dci_kinetis.h + * + * @author + * + * @version + * + * @date + * + * @brief The file contains Macro's and functions needed by the DCI layer. + * + *****************************************************************************/ + +#ifndef _USB_DCI_H +#define _USB_DCI_H +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "derivative.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define BYTES_1024 (1024) +#define BYTES_512 (512) +#define ENDPT_EP_STALL_MASK (0x02) +#define FRAME_HIGH_BYTE_SHIFT (8) + +#ifdef USB_LOWPOWERMODE +typedef enum _stopmode +{ + STOP_MODE1 = 1, /* STOP MODE 1 */ + STOP_MODE2 = 2, /* STOP MODE 2 */ + STOP_MODE3 = 3, /* STOP MODE 3 */ + STOP_MODE4 = 4 /* STOP MODE 4 */ +}STOP_MODE; +#endif + +/* USBTRC0 Initialization Parameters */ +#define _USBPHYEN (0x01) /* Use internal transceiver */ +#define _USBPUEN (0x40) /* Use internal pull-up resistor */ +#define _USBREGEN (0x04) /* Use the internal regulator */ +#define _USBRESET (0x80) + +#define UCFG_VAL (_USBPUEN|_USBREGEN) + +#define CTL_RESET_VAL (0) /* value programmed to the CTL + register in RESET */ + +#define EP_CTRL (0x0C) /* Cfg Control pipe for this endpoint */ +// HIGH_SPEED_DEVICE +#if !HIGH_SPEED_DEVICE +#define EP_OUT (0x08) /* Cfg OUT only pipe for this endpoint*/ +#define EP_IN (0x04) /* Cfg IN only pipe for this endpoint */ +#endif +#define HSHK_EN (0x01) /* Enable handshake packet */ + /* Handshake should be disable for + isochorous transfer */ +#define EP_CTL_DIS (0x10) + +#define EP_DISABLE (0) + +#define TRANSFER_INDEX(x) (x>>1) + +#define MAX_EP_BUFFER_SIZE USB_MAX_EP_BUFFER_SIZE /*Max Endpoint Buffer Size*/ + +/* Macro's to check whether corresponding INT_STAT bit is set */ +#define BUS_RESET_FLAG(x) ((x) & 1) +#define ERROR_FLAG(x) ((x) & 2) +#define SOF_TOKEN_FLAG(x) ((x) & 4) +#define SLEEP_FLAG(x) ((x) & 0x10) +#define RESUME_FLAG(x) ((x) & 0x20) +#define STALL_FLAG(x) ((x) & 0x80) +#define TOKEN_COMPL_FLAG(x) ((x) & 8) + +/* Setup the controller for Remote Wakeup */ +#define USB_DCI_WAKEUP \ +{ \ + USB0_ISTAT |= USB_ISTAT_RESUME_MASK; \ + USB0_INTEN &= ~USB_INTEN_RESUMEEN_MASK; \ + USB0_CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; \ +} + +/* control endpoint transfer types */ +#define USB_TRF_UNKNOWN (0xFF) + + +#define BDT_MIN_BUFFER_SIZE (16) /* space occupied by smallest + buffer in BDT */ + +#define BDT_MIN_BUFFER_ADDR_INC (4) /* min offset increment + correspoding to min buffer + size */ + +#define BDT_OFFSET_SHIFT (4) /* bdt offset shift */ + +#define INVALID_BDT_INDEX (0xff)/* invalid bdt index */ + +#define ENDPOINT_NUMBER_SHIFT (4) /* endpoint shift & mask to */ +#define ENDPOINT_NUMBER_MASK (0xf0)/* use in setting and getting + status */ + +#define ENDPOINT_DIRECTION_SHIFT (3) /* direction shift & mask to */ +#define ENDPOINT_DIRECTION_MASK (0x08)/* be used for STAT byte + in BDT */ + +#define SEND_CONTROL_ENDPOINT_BDT_INDEX (2) /* BDT Index for Control Endpoint + SEND direction */ +#define RECV_CONTROL_ENDPOINT_BDT_INDEX (0) /* BDT Index for Control Endpoint + RECV direction */ + +#define EPCTL_STALL (0x02)/* Stall bit in Endpoint + Control Reg */ + +#define USB_SETUP_TOKEN (0x0d)/* Setup Token PID */ +#define USB_SETUP_DIRECTION (0x80)/* Data xfer direction + for Setup packet */ + +#define INT_STAT_CLEAR_ALL (0xbf)/* Value to clear + all Interrupts */ +#define ERR_STAT_CLEAR_ALL (0xbf)/* Value to clear + all Errors */ +#define ERR_ENB_ENABLE_ALL (0xbf)/* Value to enable + all Error Interrupts */ +#define INTENB_BUS_RESET_VAL (0x9f)/* Value to enable + Interrupts in Bus Reset */ +#define INTENB_DISABLE_ALL_VAL (0x00)/* Value to disable all + Interrupts */ + +#define MAX_USB_RAM_BUFFER_INDEX (14) /* MAX possible RAM buffer + Index */ + +#define EP_START_BUFFER_ADDR (0x08)/* First USB_RAM buffer offset*/ + +#define ASSERT_RESUME_DELAY_COUNT (20000)/* Delay for assert resume, 48MHz clock */ + +#define NO_ERRORS (0) /* Init value for error */ + +#define USB_RAM_EVEN_BUFFER (0) +#define USB_RAM_ODD_BUFFER (1) + +#define SWAP16(val) (val) + +#define SWAP32(val) (val) + +/****************************************************************************** + * Types + *****************************************************************************/ +#ifdef LONG_SEND_TRANSACTION + #define LONG_TRANSACTION +#endif + +#ifdef LONG_RECEIVE_TRANSACTION + #define LONG_TRANSACTION +#endif + +typedef union { + uint_8 Byte; + struct { + uint_8 EP_HSHK :1; /* When set this bet enables an endpoint to perform handshaking during a transaction to this endpoint. This bit will generally be set unless the endpoint is Isochronous */ + uint_8 EP_STALL :1; /* When set this bit indicates that the endpoint is stalled */ + uint_8 EP_TX_EN :1; /* This bit, when set, enables the endpoint for TX transfers */ + uint_8 EP_RX_EN :1; /* This bit, when set, enables the endpoint for RX transfers */ + uint_8 EP_CTRL_DIS :1; /* This bit, when set, disables control (SETUP) transfers. When cleared, control transfers are enabled. This applies if and only if the EP_RX_EN and EP_TX_EN bits are also set */ + uint_8 :1; + uint_8 RETRY_DIS :1; /* This is a Host mode only bit and is only present in the control register for endpoint 0 (ENDPT0) */ + uint_8 HOST_WO_HUB :1; /* This is a Host mode only bit and is only present in the control register for endpoint 0 (ENDPT0) */ + } Bits; +} ENDPT0STR; + +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) +/* This structure is used to hold endpoint paramaetes and the + transaction parameters on the IO's happening on them */ +typedef struct _BDT_ELEM +{ + uint_16 len; /* endpoint max buffer len */ + uint_32 addr; /* endpoint buffer addr in USB_RAM */ +#ifdef LONG_TRANSACTION + uint_8_ptr app_buffer; /* application buffer pointer */ + USB_PACKET_SIZE app_len; /* application buffer len */ + USB_PACKET_SIZE curr_offset; /* current offset for long transactions */ +#endif + uint_8 flag; /* zero termination flag */ + uint_8 bdtmap_index; /* Corresponding to the buffer */ + uint_8 direction; /* Direction (Send/Receive) */ + uint_8 type; /* Type of Endpoint */ +} BDT_ELEM, *P_BDT_ELEM; +#if defined(__CWCC__) + #pragma options align = reset +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma pack() +#else /* gcc */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#endif + + +uint_8 USB_DCI_DeInit(void); + + /***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Device_Call_Service( + uint_8 type, + PTR_USB_DEV_EVENT_STRUCT event +); + +#ifndef OTG_BUILD +void USB_ISR(void); +#endif + +#if HIGH_SPEED_DEVICE + /* Device Queue Head and Device Transfer Descriptor Related Defination */ + #define SIZE_OF_QHD 0x40 + #define SIZE_OF_DTD0 0x20 + #define SIZE_OF_DTD1 0x20 + #define dTD_SIZE_EPIN (SIZE_OF_DTD0 + SIZE_OF_DTD1) //0x40 + #define dTD_SIZE_EPOUT (SIZE_OF_DTD0 + SIZE_OF_DTD1) //0x40 + #define BUFFER_USED_PER_EP ((SIZE_OF_QHD + dTD_SIZE_EPIN) +(SIZE_OF_QHD + dTD_SIZE_EPOUT)) //0x100 + #define ZLT_ENABLE 0 + #define ZLT_DISABLE 1 + #define IOS_NOTSET 0 + #define IOS_SET 1 + #define IOC_NOTSET 0 + #define IOC_SET 1 + #define TERMINATE 1 + #define NOT_TERMINATE 0 + #define NO_STATUS 0 + #define ACTIVE 0x00000080 + #define EPOUT_COMPLETE 0x00000001 + #define EPIN_COMPLETE 0x00010000 + #define EPOUT_PRIME 0x00000001 + #define EPIN_PRIME 0x00010000 + #define EPOUT_ENABLE 0x00000080 + #define EPIN_ENABLE 0x00800000 + #define STALL_RX 0x00000001 + #define STALL_TX 0x00010000 + + /* Maximum packet size defination */ + #define MPS_8 8 + #define MPS_64 64 + + /* enum for endpoint numbers */ + enum { + EP0, + EP1, + EP2, + EP3, + EP4, + EP5 + }; + + enum { + OUT, + IN + }; + + /* enum for data transfer type on endpoints */ + enum { + CONTROL, + ISOCHRONOUS, + BULK, + INTERRUPT + }; + + /* Status of all transaction on USB */ + typedef enum { + USB_SUCCESS, + USB_FAILURE, + USB_INVALID = -1 /* Always Keep this entry in last */ + } usb_status_t; + + /* USB Device State which are handled by DCD */ + typedef enum { + USB_DEV_DUMMY_STATE, + USB_DEV_DEFAULT_STATE, + USB_DEV_ADDRESSED_STATE, + USB_DEV_CONFIGURED_STATE + } usb_state_t; +#endif // HIGH_SPEED_DEVICE + +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dciapi.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dciapi.h new file mode 100644 index 0000000..d190ee8 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_dciapi.h @@ -0,0 +1,269 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_dciapi.h + * + * @author + * + * @version + * + * @date Jun-05-2009 + * + * @brief The file contains DCI api function definetions . + * + *****************************************************************************/ + +#ifndef _USB_DCIAPI_H +#define _USB_DCIAPI_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_devapi.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_SUPPORTED_ENDPOINTS (USB_SERVICE_MAX_EP + 1) + /* Maximum endpoints supported */ +#define MIN_SUPPORTED_ENDPOINTS (1) /* Minimum endpoints supported */ +#define DOUBLE_BUFFERED_ENPOINT_NUMBER (0) /* First double buffered endpoint */ + +#ifdef MCU_MK70F12 +#define NUM_USB_CONTROLLERS (2) +#else +#define NUM_USB_CONTROLLERS (1) +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef enum USB_Controllers_t +{ + MAX3353, + ULPI +}USB_Controllers_t; + +#if HIGH_SPEED_DEVICE +typedef struct dqh_setup_t { + unsigned int dqh_word0; + unsigned int dqh_word1; + unsigned int dqh_word2; + unsigned int dqh_word3; + unsigned int dqh_word4; + unsigned int dqh_word5; + unsigned int dqh_word6; + unsigned int dqh_word7; + unsigned int dqh_word8; + unsigned int dqh_word9; + unsigned int dqh_word10; + unsigned int dqh_word11; +} dqh_setup_t; + +typedef struct dtd_setup_t { + unsigned int dtd_word0; + unsigned int dtd_word1; + unsigned int dtd_word2; + unsigned int dtd_word3; + unsigned int dtd_word4; + unsigned int dtd_word5; + unsigned int dtd_word6; + unsigned int dtd_word7; +} dtd_setup_t; + +typedef struct dqh_t { + unsigned int dqh_base; + unsigned int next_link_ptr; + unsigned int buffer_ptr0; + unsigned int buffer_ptr1; + unsigned int buffer_ptr2; + unsigned int buffer_ptr3; + unsigned int buffer_ptr4; + unsigned short total_bytes; + unsigned short mps; + unsigned short current_offset; + unsigned char zlt; + unsigned char ios; + unsigned char terminate; + unsigned char ioc; + unsigned char status; + unsigned char mult; +} dqh_t; + +typedef struct dtd_t { + unsigned int dtd_base; + unsigned int next_link_ptr; + unsigned int buffer_ptr0; + unsigned int buffer_ptr1; + unsigned int buffer_ptr2; + unsigned int buffer_ptr3; + unsigned int buffer_ptr4; + unsigned short total_bytes; + unsigned short current_offset; + unsigned char terminate; + unsigned char ioc; + unsigned char status; +} dtd_t; + +typedef struct { + unsigned int ep_dqh_base_addrs; /* Base Address of Queue Header */ + unsigned int ep_dtd_base_addrs; /* Base Address of Transfer Descriptor */ + unsigned int ep0_buffer_addrs; /* Buffer Addres for EP0 IN */ + unsigned int buffer1_address; /* Buffer1 address for bulk transfer */ + unsigned int buffer1_status; /* Status of Buffer1 */ + unsigned int buffer2_address; /* Buffer2 address for bulk transfer */ + unsigned int buffer2_status; /* Status of Buffer2 */ +} buffer_map_t; + +/* USB standard device request*/ +typedef struct usb_standrd_device_request { + unsigned char bmRequestType; + unsigned char bRequest; + unsigned short wValue; + unsigned short wIndex; + unsigned short wLength; +} usb_standard_device_request_t; + +#endif // HIGH_SPEED_DEVICE + + /***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_DCI_Init( + uint_8 controller_ID, + uint_8 bVregEn +); + + +extern uint_8 USB_DCI_Init_EndPoint( + uint_8 controller_ID, + USB_EP_STRUCT_PTR ep_ptr, + boolean double_buffered +); + +extern uint_8 USB_DCI_Init_EndPoint( + uint_8 controller_ID, + USB_EP_STRUCT_PTR ep_ptr, + boolean flag +); + +extern uint_8 USB_DCI_Cancel_Transfer( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern uint_8 USB_DCI_Deinit_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Stall_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Unstall_EndPoint( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Get_Setup_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr +); + +extern uint_8 USB_DCI_Get_Transfer_Status( + uint_8 controller_ID, + uint_8 ep_num, + uint_8 direction +); + +extern void USB_DCI_Clear_DATA0_Endpoint( + uint_8 ep_num, + uint_8 direction +); + +extern uint_8 USB_DCI_Recv_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern uint_8 USB_DCI_Send_Data( + uint_8 controller_ID, + uint_8 ep_num, + uchar_ptr buff_ptr, + USB_PACKET_SIZE size +); + +extern void USB_DCI_Set_Address( + uint_8 controller_ID, + uint_8 address +); + +extern void USB_DCI_Shutdown( + uint_8 controller_ID +); + +extern void USB_DCI_Assert_Resume( + uint_8 controller_ID +); + +extern void Clear_Mem(uint_8* start_addr,uint_32 count, uint_8 val); + +#define USB_DCI_Cancel_Transfer _usb_device_cancel_transfer + +#define USB_DCI_Recv_Data _usb_device_recv_data + +#define USB_DCI_Send_Data _usb_device_send_data + +#define USB_DCI_Shutdown _usb_device_shutdown + +#define USB_DCI_Stall_EndPoint _usb_device_stall_endpoint + +#define USB_DCI_Unstall_EndPoint _usb_device_unstall_endpoint + +#define USB_DCI_Get_Transfer_Status _usb_device_get_transfer_status + +#define USB_DCI_Clear_DATA0_Endpoint _usb_device_clear_data0_endpoint + +#define USB_DCI_Get_Setup_Data _usb_device_read_setup_data + +#define USB_DCI_Set_Address _usb_device_set_address + +#define USB_DCI_Assert_Resume _usb_device_assert_resume + +#endif + + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.c new file mode 100644 index 0000000..1ba1931 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.c @@ -0,0 +1,956 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_descriptor.c + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief This file contains USB descriptors for Virtual COM Loopback + * Application + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "derivative.h" +#include "types.h" +#include "usb_class.h" +#include "usb_descriptor.h" + +#if (defined __MCF52xxx_H__)||(defined __MK_xxx_H__) +/* Put CFV2 descriptors in RAM */ +#define USB_DESC_CONST +#else +#define USB_DESC_CONST const +#endif + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ +/* structure containing details of all the endpoints used by this device */ +USB_DESC_CONST USB_ENDPOINTS usb_desc_ep = +{ + CDC_DESC_ENDPOINT_COUNT, + { + #if DATA_CLASS_SUPPORT + #if DIC_ISOCHRONOUS_SETTING + { + DIC_ISO_IN_ENDPOINT, + USB_ISOCHRONOUS_PIPE, + USB_SEND, + DIC_ISO_IN_ENDP_PACKET_SIZE + }, + { + DIC_ISO_OUT_ENDPOINT, + USB_ISOCHRONOUS_PIPE, + USB_RECV, + DIC_ISO_OUT_ENDP_PACKET_SIZE + } + #else + { + DIC_BULK_IN_ENDPOINT, + USB_BULK_PIPE, + USB_SEND, + DIC_BULK_IN_ENDP_PACKET_SIZE + }, + { + DIC_BULK_OUT_ENDPOINT, + USB_BULK_PIPE, + USB_RECV, + DIC_BULK_OUT_ENDP_PACKET_SIZE + } + #endif + #endif + #if CIC_NOTIF_ELEM_SUPPORT + , + { + CIC_NOTIF_ENDPOINT, + USB_INTERRUPT_PIPE, + USB_SEND, + CIC_NOTIF_ENDP_PACKET_SIZE + } + #endif + + } +}; + +uint_8 USB_DESC_CONST g_device_descriptor[DEVICE_DESCRIPTOR_SIZE] = +{ + DEVICE_DESCRIPTOR_SIZE, /* Device Descriptor Size */ + USB_DEVICE_DESCRIPTOR, /* Device Type of descriptor */ + 0x00, 0x02, /* BCD USB version */ + 0x02, /* Device Class is indicated in + the interface descriptors */ + 0x00, /* Device Subclass is indicated + in the interface descriptors */ + 0x00, /* Device Protocol */ + CONTROL_MAX_PACKET_SIZE, /* Max Packet size */ +#if 0 /* << EST */ + 0xA2,0x15, /* Vendor ID */ + 0x00,0x03, /* 0300 is our Product ID for CDC */ +#else + (0x2504&0xFF),((0x2504>>8)&0xFF), /* Vendor ID from properties */ + (0x0300&0xFF),((0x0300>>8)&0xFF), /* Product ID from properties */ +#endif + 0x02,0x00, /* BCD Device version */ + 0x01, /* Manufacturer string index */ + 0x02, /* Product string index */ + 0x03, /* Serial number string index */ + 0x01 /* Number of configurations */ +}; + +uint_8 USB_DESC_CONST g_config_descriptor[CONFIG_DESC_SIZE] = +{ + CONFIG_ONLY_DESC_SIZE, /* Configuration Descriptor Size */ + USB_CONFIG_DESCRIPTOR, /* "Configuration" type of descriptor */ + CONFIG_DESC_SIZE, 0x00, /* Total length of the Configuration descriptor */ + (uint_8)(1+DATA_CLASS_SUPPORT),/*NumInterfaces*/ + 0x01, /* Configuration Value */ + 0x00, /* Configuration Description String Index*/ +#if 0 + BUS_POWERED|SELF_POWERED|(REMOTE_WAKEUP_SUPPORT<>1), /* Current draw from bus, e.g. is in 2 mA units */ + + /* CIC INTERFACE DESCRIPTOR */ + IFACE_ONLY_DESC_SIZE, + USB_IFACE_DESCRIPTOR, + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + CIC_ENDP_COUNT, /* management and notification(optional)element present */ + 0x02, /* Communication Interface Class */ + CIC_SUBCLASS_CODE, + CIC_PROTOCOL_CODE, + 0x00, /* Interface Description String Index*/ + + /* CDC Class-Specific descriptor */ + 0x05, /* size of Functional Desc in bytes */ + USB_CS_INTERFACE, /* descriptor type*/ + HEADER_FUNC_DESC, + 0x10, 0x01, /* USB Class Definitions for CDC spec release number in BCD */ + + 0x05, /* Size of this descriptor */ + USB_CS_INTERFACE, /* descriptor type*/ + CALL_MANAGEMENT_FUNC_DESC, + 0x01,/*may use 0x03 */ /* device handales call management itself(D0 set) + and will process commands multiplexed over the data interface */ + 0x01, /* Indicates multiplexed commands are + handled via data interface */ + + 0x04, /* Size of this descriptor */ + USB_CS_INTERFACE, /* descriptor type*/ + ABSTRACT_CONTROL_FUNC_DESC, + 0x06, /*may use 0x0F */ /* Device Supports all commands for ACM - CDC + PSTN SubClass bmCapabilities */ + + 0x05, /* size of Functional Desc in bytes */ + USB_CS_INTERFACE, /* descriptor type*/ + UNION_FUNC_DESC, + 0x00, /* Interface Number of Control */ + 0x01 /* Interface Number of Subordinate (Data Class) Interface */ + +#if CIC_NOTIF_ELEM_SUPPORT /*Endpoint descriptor */ + , /* Comma Added if NOTIF ELEM IS TO BE ADDED */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + CIC_NOTIF_ENDPOINT|(USB_SEND << 7), + USB_INTERRUPT_PIPE, + CIC_NOTIF_ENDP_PACKET_SIZE, 0x00, + 0x0A +#endif + +#if DATA_CLASS_SUPPORT + , /* Comma Added if DATA_CLASS_DESC IS TO BE ADDED */ + IFACE_ONLY_DESC_SIZE, + USB_IFACE_DESCRIPTOR, + (uint_8)(0x00+DATA_CLASS_SUPPORT), /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + DIC_ENDP_COUNT, /* notification element included */ + 0x0A, /* DATA Interface Class */ + 0x00, /* Data Interface SubClass Code */ + DIC_PROTOCOL_CODE, + 0x00, /* Interface Description String Index*/ + + #if ! DIC_ISOCHRONOUS_SETTING + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_BULK_IN_ENDPOINT|(USB_SEND << 7), + USB_BULK_PIPE, + DIC_BULK_IN_ENDP_PACKET_SIZE, 0x00, + 0x00,/* This value is ignored for Bulk ENDPOINT */ + + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_BULK_OUT_ENDPOINT|(USB_RECV << 7), + USB_BULK_PIPE, + DIC_BULK_OUT_ENDP_PACKET_SIZE, 0x00, + 0x00 /* This value is ignored for Bulk ENDPOINT */ + #else + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_ISO_IN_ENDPOINT|(USB_SEND << 7), + USB_ISOCHRONOUS_PIPE, + DIC_ISO_IN_ENDP_PACKET_SIZE, 0x00, + 0x01,/* This value is for Iso ENDPOINT */ + + /*Endpoint descriptor */ + ENDP_ONLY_DESC_SIZE, + USB_ENDPOINT_DESCRIPTOR, + DIC_ISO_OUT_ENDPOINT|(USB_RECV << 7), + USB_ISOCHRONOUS_PIPE, + DIC_ISO_OUT_ENDP_PACKET_SIZE, 0x00, + 0x01 /* This value is for Iso ENDPOINT */ + #endif +#endif +}; + +uint_8 USB_DESC_CONST USB_STR_0[USB_STR_0_SIZE+USB_STR_DESC_SIZE] = + {sizeof(USB_STR_0), + USB_STRING_DESCRIPTOR, + 0x09, + 0x04/*equiavlent to 0x0409*/ + }; + +uint_8 USB_DESC_CONST USB_STR_1[USB_STR_1_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_1), + USB_STRING_DESCRIPTOR, +#if 0 /* << EST */ + 'F',0, + 'R',0, + 'E',0, + 'E',0, + 'S',0, + 'C',0, + 'A',0, + 'L',0, + 'E',0, + ' ',0, + 'S',0, + 'E',0, + 'M',0, + 'I',0, + 'C',0, + 'O',0, + 'N',0, + 'D',0, + 'U',0, + 'C',0, + 'T',0, + 'O',0, + 'R',0, + ' ',0, + 'I',0, + 'N',0, + 'C',0, + '.',0 +#else + 'F',0, + 'R',0, + 'E',0, + 'E',0, + 'S',0, + 'C',0, + 'A',0, + 'L',0, + 'E',0, + ' ',0, + 'I',0, + 'N',0, + 'C',0, + '.',0, +#endif + }; + + +uint_8 USB_DESC_CONST USB_STR_2[USB_STR_2_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_2), + USB_STRING_DESCRIPTOR, +#if 0 /* << EST */ + ' ',0, + ' ',0, + #ifdef __MK_xxx_H__ + 'M',0, + 'K',0, + #elif (defined __MCF52xxx_H__) + 'C',0, + 'F',0, + #elif (defined MCU_mcf51jf128) + 'J',0, + 'F',0, + #else + 'J',0, + 'M',0, + #endif + ' ',0, + 'C',0, + 'D',0, + 'C',0, + ' ',0, + 'D',0, + 'E',0, + 'M',0, + 'O',0, + ' ',0 +#else + 'F',0, + 'S',0, + 'L',0, + ' ',0, + 'C',0, + 'D',0, + 'C',0, + ' ',0, + 'D',0, + 'E',0, + 'V',0, + 'I',0, + 'C',0, + 'E',0, +#endif + }; + +/* string descriptor for serial number */ +uint_8 USB_DESC_CONST USB_STR_3[USB_STR_3_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_3), + USB_STRING_DESCRIPTOR, + '0',0, + '0',0, + '0',0, + '1',0, + '2',0, + '3',0, + 'A',0, + 'B',0, + 'C',0, + }; + +uint_8 USB_DESC_CONST USB_STR_n[USB_STR_n_SIZE+USB_STR_DESC_SIZE] + = { sizeof(USB_STR_n), + USB_STRING_DESCRIPTOR, + 'B',0, + 'A',0, + 'D',0, + ' ',0, + 'S',0, + 'T',0, + 'R',0, + 'I',0, + 'N',0, + 'G',0, + ' ',0, + 'I',0, + 'N',0, + 'D',0, + 'E',0, + 'X',0 + }; + + +USB_PACKET_SIZE const g_std_desc_size[USB_MAX_STD_DESCRIPTORS+1] = + {0, + DEVICE_DESCRIPTOR_SIZE, + CONFIG_DESC_SIZE, + 0, /* string */ + 0, /* Interface */ + 0, /* Endpoint */ + 0, /* Device Qualifier */ + 0 /* other speed config */ + }; + +uint_8_ptr const g_std_descriptors[USB_MAX_STD_DESCRIPTORS+1] = + { + NULL, + (uint_8_ptr)g_device_descriptor, + (uint_8_ptr)g_config_descriptor, + NULL, /* string */ + NULL, /* Interface */ + NULL, /* Endpoint */ + NULL, /* Device Qualifier */ + NULL /* other speed config*/ + }; + +uint_8 const g_string_desc_size[USB_MAX_STRING_DESCRIPTORS+1] = + { + sizeof(USB_STR_0), + sizeof(USB_STR_1), + sizeof(USB_STR_2), + sizeof(USB_STR_3), /* << EST serial number */ + sizeof(USB_STR_n) + }; + +uint_8_ptr const g_string_descriptors[USB_MAX_STRING_DESCRIPTORS+1] = + { + (uint_8_ptr)USB_STR_0, + (uint_8_ptr)USB_STR_1, + (uint_8_ptr)USB_STR_2, + (uint_8_ptr)USB_STR_3, /* << EST serial number */ + (uint_8_ptr)USB_STR_n + }; + +#ifdef __HC08__ /* << EST */ +#pragma MESSAGE DISABLE C4800 /* implicit cast in assignment */ +#endif +USB_ALL_LANGUAGES g_languages = { USB_STR_0, sizeof(USB_STR_0), + { + { + (uint_16)0x0409, + (const uint_8 **)g_string_descriptors, + g_string_desc_size + } + } + }; +#ifdef __HC08__ /* << EST */ +#pragma MESSAGE DEFAULT C4800 +#endif + +uint_8 const g_valid_config_values[USB_MAX_CONFIG_SUPPORTED+1]={0,1}; + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +#ifdef _MC9S08JS16_H +#pragma DATA_SEG APP_DATA +#endif + +static uint_8 g_line_coding[USB_MAX_SUPPORTED_INTERFACES][LINE_CODING_SIZE] = +{ + { (LINE_CODE_DTERATE_IFACE0>> 0) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>> 8) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>>16) & 0x000000FF, + (LINE_CODE_DTERATE_IFACE0>>24) & 0x000000FF, + /*e.g. 0x00,0xC2,0x01,0x00 : 0x0001C200 is 115200 bits per second */ + LINE_CODE_CHARFORMAT_IFACE0, + LINE_CODE_PARITYTYPE_IFACE0, + LINE_CODE_DATABITS_IFACE0 + } +}; + +static uint_8 g_abstract_state[USB_MAX_SUPPORTED_INTERFACES][COMM_FEATURE_DATA_SIZE] = +{ + { (STATUS_ABSTRACT_STATE_IFACE0>>0) & 0x00FF, + (STATUS_ABSTRACT_STATE_IFACE0>>8) & 0x00FF + } +}; + +static uint_8 g_country_code[USB_MAX_SUPPORTED_INTERFACES][COMM_FEATURE_DATA_SIZE] = +{ + { (COUNTRY_SETTING_IFACE0>>0) & 0x00FF, + (COUNTRY_SETTING_IFACE0>>8) & 0x00FF + } +}; + +static uint_8 g_alternate_interface[USB_MAX_SUPPORTED_INTERFACES]; + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + + + /***************************************************************************** + * Local Functions - None + *****************************************************************************/ + +/***************************************************************************** + * Global Functions + *****************************************************************************/ +/**************************************************************************//*! + * + * @name USB_Desc_Get_Descriptor + * + * @brief The function returns the correponding descriptor + * + * @param controller_ID : Controller ID + * @param type : type of descriptor requested + * @param sub_type : string index for string descriptor + * @param index : string descriptor language Id + * @param descriptor : output descriptor pointer + * @param size : size of descriptor returned + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is used to pass the pointer to the requested descriptor + *****************************************************************************/ +uint_8 USB_Desc_Get_Descriptor ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 type, /* [IN] type of descriptor requested */ + uint_8 str_num, /* [IN] string index for string descriptor */ + uint_16 index, /* [IN] string descriptor language Id */ + uint_8_ptr *descriptor, /* [OUT] output descriptor pointer */ + USB_PACKET_SIZE *size /* [OUT] size of descriptor returned */ +) +{ + UNUSED (controller_ID) + + /* string descriptors are handled saperately */ + if (type == USB_STRING_DESCRIPTOR) + { + if(index == 0) + { + /* return the string and size of all languages */ + *descriptor = (uint_8_ptr)g_languages.languages_supported_string; + *size = g_languages.languages_supported_size; + } else + { + uint_8 lang_id=0; + uint_8 lang_index=USB_MAX_LANGUAGES_SUPPORTED; + + for(;lang_id< USB_MAX_LANGUAGES_SUPPORTED;lang_id++) + { + /* check whether we have a string for this language */ + if(index == g_languages.usb_language[lang_id].language_id) + { /* check for max descriptors */ + if(str_num < USB_MAX_STRING_DESCRIPTORS) + { /* setup index for the string to be returned */ + lang_index=str_num; + } + + break; + } + + } + + /* set return val for descriptor and size */ + *descriptor = (uint_8_ptr)g_languages.usb_language[lang_id]. + lang_desc[lang_index]; + *size = g_languages.usb_language[lang_id]. + lang_desc_size[lang_index]; + } + + } + else if (type < USB_MAX_STD_DESCRIPTORS+1) + { + /* Set return val for descriptor and size */ + *descriptor = (uint_8_ptr)g_std_descriptors [type]; + + /* if there is no descriptor then return error */ + if(*descriptor == NULL) + { + return USBERR_INVALID_REQ_TYPE; + } + + *size = g_std_desc_size[type]; + } + else /* invalid descriptor */ + { + return USBERR_INVALID_REQ_TYPE; + } + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Interface + * + * @brief The function returns the alternate interface + * + * @param controller_ID : Controller Id + * @param interface : Interface number + * @param alt_interface : Output alternate interface + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is called by the framework module to get the current interface + *****************************************************************************/ +uint_8 USB_Desc_Get_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] interface number */ + uint_8_ptr alt_interface /* [OUT] output alternate interface */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get alternate interface*/ + *alt_interface = g_alternate_interface[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Interface + * + * @brief The function sets the alternate interface + * + * @param controller_ID : Controller Id + * @param interface : Interface number + * @param alt_interface : Input alternate interface + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * This function is called by the framework module to set the interface + *****************************************************************************/ +uint_8 USB_Desc_Set_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] interface number */ + uint_8 alt_interface /* [IN] input alternate interface */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set alternate interface*/ + g_alternate_interface[interface]=alt_interface; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Valid_Configation + * + * @brief The function checks whether the configuration parameter + * input is valid or not + * + * @param controller_ID : Controller Id + * @param config_val : Configuration value + * + * @return TRUE When Valid + * FALSE When Error + ***************************************************************************** + * This function checks whether the configuration is valid or not + *****************************************************************************/ +boolean USB_Desc_Valid_Configation ( + uint_8 controller_ID,/*[IN] Controller ID */ + uint_16 config_val /*[IN] configuration value */ +) +{ + uint_8 loop_index=0; + UNUSED (controller_ID) + + /* check with only supported val right now */ + while(loop_index < (USB_MAX_CONFIG_SUPPORTED+1)) + { + if(config_val == g_valid_config_values[loop_index]) + { + return TRUE; + } + loop_index++; + } + + return FALSE; +} +/**************************************************************************//*! + * + * @name USB_Desc_Valid_Interface + * + * @brief The function checks whether the interface parameter + * input is valid or not + * + * @param controller_ID : Controller Id + * @param interface : Target interface + * + * @return TRUE When Valid + * FALSE When Error + ***************************************************************************** + * This function checks whether the interface is valid or not + *****************************************************************************/ +boolean USB_Desc_Valid_Interface ( + uint_8 controller_ID, /*[IN] Controller ID */ + uint_8 interface /*[IN] target interface */ +) +{ + uint_8 loop_index=0; + UNUSED (controller_ID) + + /* check with only supported val right now */ + while(loop_index < USB_MAX_SUPPORTED_INTERFACES) + { + if(interface == g_alternate_interface[loop_index]) + { + return TRUE; + } + loop_index++; + } + + return FALSE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Remote_Wakeup + * + * @brief The function checks whether the remote wakeup is supported or not + * + * @param controller_ID : Controller ID + * + * @return REMOTE_WAKEUP_SUPPORT (TRUE) - if remote wakeup supported + ***************************************************************************** + * This function returns remote wakeup is supported or not + *****************************************************************************/ +boolean USB_Desc_Remote_Wakeup ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return REMOTE_WAKEUP_SUPPORT; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Endpoints + * + * @brief The function returns with the list of all non control endpoints used + * + * @param controller_ID : Controller ID + * + * @return pointer to USB_ENDPOINTS + ***************************************************************************** + * This function returns the information about all the non control endpoints + * implemented + *****************************************************************************/ +void* USB_Desc_Get_Endpoints ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return (void*)&usb_desc_ep; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Line_Coding + * + * @brief The function returns the Line Coding/Configuraion + * + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param coding_data : Output line coding data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns current Line Coding Parameters + *****************************************************************************/ +uint_8 USB_Desc_Get_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *coding_data /* [OUT] Line Coding Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *coding_data = g_line_coding[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Line_Coding + * + * @brief The function sets the Line Coding/Configuraion + * + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param coding_data : Output line coding data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets Line Coding Structure with the HOST specified values + *****************************************************************************/ +uint_8 USB_Desc_Set_Line_Coding ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *coding_data /* [IN] Line Coding Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set line coding data*/ + for (count = 0; count < LINE_CODING_SIZE; count++) + { + g_line_coding[interface][count] = *((*coding_data + + USB_SETUP_PKT_SIZE) + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Abstract_State + * + * @brief The function gets the current setting for communication feature + * (ABSTRACT_STATE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns ABSTRACT STATE Communication Feature to the Host + *****************************************************************************/ +uint_8 USB_Desc_Get_Abstract_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *feature_data = g_abstract_state[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Get_Country_Setting + * + * @brief The function gets the current setting for communication feature + * (COUNTRY_CODE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Returns the country Code to the Host + *****************************************************************************/ +uint_8 USB_Desc_Get_Country_Setting ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + UNUSED (controller_ID) + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* get line coding data*/ + *feature_data = g_country_code[interface]; + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Abstract_State + * + * @brief The function gets the current setting for communication feature + * (ABSTRACT_STATE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets the ABSTRACT State specified by the Host + *****************************************************************************/ +uint_8 USB_Desc_Set_Abstract_State ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + /* set Abstract State Feature*/ + for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) + { + g_abstract_state[interface][count] = *(*feature_data + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} + +/**************************************************************************//*! + * + * @name USB_Desc_Set_Country_Setting + * + * @brief The function gets the current setting for communication feature + * (COUNTRY_CODE) + * @param controller_ID : Controller ID + * @param interface : Interface number + * @param feature_data : Output comm feature data + * + * @return USB_OK When Successfull + * USBERR_INVALID_REQ_TYPE when Error + ***************************************************************************** + * Sets the country code specified by the HOST + *****************************************************************************/ +uint_8 USB_Desc_Set_Country_Setting( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 interface, /* [IN] Interface Number */ + uint_8_ptr *feature_data /* [OUT] Output Comm Feature Data */ +) +{ + uint_8 count; + UNUSED (controller_ID) + + /* if interface valid */ + if(interface < USB_MAX_SUPPORTED_INTERFACES) + { + for (count = 0; count < COMM_FEATURE_DATA_SIZE; count++) + { + g_country_code[interface][count] = *(*feature_data + count); + } + return USB_OK; + } + + return USBERR_INVALID_REQ_TYPE; +} diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.h new file mode 100644 index 0000000..ddabd3d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_descriptor.h @@ -0,0 +1,302 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_descriptor.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file is a header file for USB Descriptors required for Virtual + * COM Loopback Application + *****************************************************************************/ + +#ifndef _USB_DESCRIPTOR_H +#define _USB_DESCRIPTOR_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_class.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define REMOTE_WAKEUP_SUPPORT (FALSE) +#define DATA_CLASS_SUPPORT (TRUE) +#define CIC_NOTIF_ELEM_SUPPORT (TRUE) /* Mandatory */ +#define DIC_ISOCHRONOUS_SETTING (FALSE) + +#define IMPLEMENT_QUEUING (TRUE) + +/* Communication Class SubClass Codes */ +#define DIRECT_LINE_CONTROL_MODEL (0x01) +#define ABSTRACT_CONTROL_MODEL (0x02) +#define TELEPHONE_CONTROL_MODEL (0x03) +#define MULTI_CHANNEL_CONTROL_MODEL (0x04) +#define CAPI_CONTROL_MOPDEL (0x05) +#define ETHERNET_NETWORKING_CONTROL_MODEL (0x06) +#define ATM_NETWORKING_CONTROL_MODEL (0x07) +#define WIRELESS_HANDSET_CONTROL_MODEL (0x08) +#define DEVICE_MANAGEMENT (0x09) +#define MOBILE_DIRECT_LINE_MODEL (0x0A) +#define OBEX (0x0B) +#define ETHERNET_EMULATION_MODEL (0x0C) + +/* Communication Class Protocol Codes */ +#define NO_CLASS_SPECIFIC_PROTOCOL (0x00) +#define AT_250_PROTOCOL (0x01) +#define AT_PCCA_101_PROTOCOL (0x02) +#define AT_PCCA_101_ANNEX_O (0x03) +#define AT_GSM_7_07 (0x04) +#define AT_3GPP_27_007 (0x05) +#define AT_TIA_CDMA (0x06) +#define ETHERNET_EMULATION_PROTOCOL (0x07) +#define EXTERNAL_PROTOCOL (0xFE) +#define VENDOR_SPECIFIC (0xFF) + +/* Data Class Protocol Codes */ +/* #define NO_CLASS_SPECIFIC_PROTOCOL (0x00) */ +#define PYHSICAL_INTERFACE_PROTOCOL (0x30) +#define HDLC_PROTOCOL (0x31) +#define TRANSPARENT_PROTOCOL (0x32) +#define MANAGEMENT_PROTOCOL (0x50) +#define DATA_LINK_Q931_PROTOCOL (0x51) +#define DATA_LINK_Q921_PROTOCOL (0x52) +#define DATA_COMPRESSION_V42BIS (0x90) +#define EURO_ISDN_PROTOCOL (0x91) +#define RATE_ADAPTION_ISDN_V24 (0x92) +#define CAPI_COMMANDS (0x93) +#define HOST_BASED_DRIVER (0xFD) +#define CDC_UNIT_FUNCTIONAL (0xFE) +/* #define VENDOR_SPECIFIC (0xFF) */ + +/* Descriptor SubType in Communications Class Functional Descriptors */ +#define HEADER_FUNC_DESC (0x00) +#define CALL_MANAGEMENT_FUNC_DESC (0x01) +#define ABSTRACT_CONTROL_FUNC_DESC (0x02) +#define DIRECT_LINE_FUNC_DESC (0x03) +#define TELEPHONE_RINGER_FUNC_DESC (0x04) +#define TELEPHONE_REPORT_FUNC_DESC (0x05) +#define UNION_FUNC_DESC (0x06) +#define COUNTRY_SELECT_FUNC_DESC (0x07) +#define TELEPHONE_MODES_FUNC_DESC (0x08) +#define USB_TERMINAL_FUNC_DESC (0x09) +#define NETWORK_CHANNEL_FUNC_DESC (0x0A) +#define PROTOCOL_UNIT_FUNC_DESC (0x0B) +#define EXTENSION_UNIT_FUNC_DESC (0x0C) +#define MULTI_CHANNEL_FUNC_DESC (0x0D) +#define CAPI_CONTROL_FUNC_DESC (0x0E) +#define ETHERNET_NETWORKING_FUNC_DESC (0x0F) +#define ATM_NETWORKING_FUNC_DESC (0x10) +#define WIRELESS_CONTROL_FUNC_DESC (0x11) +#define MOBILE_DIRECT_LINE_FUNC_DESC (0x12) +#define MDLM_DETAIL_FUNC_DESC (0x13) +#define DEVICE_MANAGEMENT_FUNC_DESC (0x14) +#define OBEX_FUNC_DESC (0x15) +#define COMMAND_SET_FUNC_DESC (0x16) +#define COMMAND_SET_DETAIL_FUNC_DESC (0x17) +#define TELEPHONE_CONTROL_FUNC_DESC (0x18) +#define OBEX_SERVICE_ID_FUNC_DESC (0x19) + + +#define CIC_SUBCLASS_CODE ABSTRACT_CONTROL_MODEL +#define CIC_PROTOCOL_CODE NO_CLASS_SPECIFIC_PROTOCOL +#define DIC_PROTOCOL_CODE NO_CLASS_SPECIFIC_PROTOCOL +#define CIC_ENDP_COUNT (0+(CIC_NOTIF_ELEM_SUPPORT & 0x01) * 1) +#define DIC_ENDP_COUNT (2) + +#define CIC_NOTIF_ENDPOINT (3) +#define CIC_NOTIF_ENDP_PACKET_SIZE (16) +#define DIC_BULK_IN_ENDPOINT (1) +#define DIC_BULK_IN_ENDP_PACKET_SIZE (16)/* max supported is 64 */ +#define DIC_BULK_OUT_ENDPOINT (2) +#define DIC_BULK_OUT_ENDP_PACKET_SIZE (16)/* max supported is 64*/ + +#if DIC_ISOCHRONOUS_SETTING +#define DIC_ISO_IN_ENDPOINT (1) +#define DIC_ISO_IN_ENDP_PACKET_SIZE (64) +#define DIC_ISO_OUT_ENDPOINT (2) +#define DIC_ISO_OUT_ENDP_PACKET_SIZE (64) +#endif +#define REMOTE_WAKEUP_SHIFT (5) + +/* Various descriptor sizes */ +#define DEVICE_DESCRIPTOR_SIZE (18) +#define CONFIG_ONLY_DESC_SIZE (9) +#define CONFIG_DESC_SIZE (CONFIG_ONLY_DESC_SIZE + 28 + \ + (CIC_NOTIF_ELEM_SUPPORT & 0x01) \ + * 7 + DATA_CLASS_SUPPORT * 23) +#define DEVICE_QUALIFIER_DESCRIPTOR_SIZE (10) +#define IFACE_ONLY_DESC_SIZE (9) +#define ENDP_ONLY_DESC_SIZE (7) + +/* Max descriptors provided by the Application */ +#define USB_MAX_STD_DESCRIPTORS (7) + +/* Max configuration supported by the Application */ +#define USB_MAX_CONFIG_SUPPORTED (1) + +/* Max string descriptors supported by the Application */ +#define USB_MAX_STRING_DESCRIPTORS (4) /* << EST added one more for serial number */ + +/* Max language codes supported by the USB */ +#define USB_MAX_LANGUAGES_SUPPORTED (1) + +/* string descriptors sizes */ +#define USB_STR_DESC_SIZE (2) +#define USB_STR_0_SIZE (2) +#define USB_STR_1_SIZE (2*14) /* bus reported vendor string */ +#define USB_STR_2_SIZE (2*14) /* bus reported device description string */ +#define USB_STR_3_SIZE (2*9) /* serial number descriptor string */ +#define USB_STR_n_SIZE (32) + +/* descriptors codes */ +#define USB_DEVICE_DESCRIPTOR (1) +#define USB_CONFIG_DESCRIPTOR (2) +#define USB_STRING_DESCRIPTOR (3) +#define USB_IFACE_DESCRIPTOR (4) +#define USB_ENDPOINT_DESCRIPTOR (5) +#define USB_DEVQUAL_DESCRIPTOR (6) +#define USB_CS_INTERFACE (0x24) +#define USB_CS_ENDPOINT (0x25) + +#define USB_MAX_SUPPORTED_INTERFACES (2) + +/* Implementation Specific Macros */ +#define LINE_CODING_SIZE (0x07) +#define COMM_FEATURE_DATA_SIZE (0x02) + +#define LINE_CODE_DTERATE_IFACE0 (115200) /*e.g 9600 is 0x00002580 */ +#define LINE_CODE_CHARFORMAT_IFACE0 (0x00) /* 1 stop bit */ +#define LINE_CODE_PARITYTYPE_IFACE0 (0x00) /* No Parity */ +#define LINE_CODE_DATABITS_IFACE0 (0x08) /* Data Bits Format */ + +#define LINE_CODE_DTERATE_IFACE1 (9600) /*e.g. 115200 is 0x0001C200*/ +#define LINE_CODE_CHARFORMAT_IFACE1 (0x00) /* 1 stop bit */ +#define LINE_CODE_PARITYTYPE_IFACE1 (0x00) /* No Parity */ +#define LINE_CODE_DATABITS_IFACE1 (0x08) /* Data Bits Format */ + +#define STATUS_ABSTRACT_STATE_IFACE0 (0x0000) /* Disable Multiplexing + ENDP in this interface will + continue to accept/offer data*/ +#define STATUS_ABSTRACT_STATE_IFACE1 (0x0000) /* Disable Multiplexing + ENDP in this interface will + continue to accept/offer data*/ +#define COUNTRY_SETTING_IFACE0 (0x0000) /* Country Code in the format as + defined in [ISO3166] */ +#define COUNTRY_SETTING_IFACE1 (0x0000) /* Country Code in the format as + defined in [ISO3166] */ + +/* Notifications Support */ +#define PSTN_SUBCLASS_NOTIF_SUPPORT (TRUE) +#define WMC_SUBCLASS_NOTIF_SUPPORT (FALSE) +#define CDC_CLASS_NOTIF_SUPPORT (FALSE) + +#define CDC_DESC_ENDPOINT_COUNT (CIC_ENDP_COUNT+(DATA_CLASS_SUPPORT & 0x01) \ + *DIC_ENDP_COUNT) + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef const struct _USB_LANGUAGE +{ + uint_16 const language_id; /* Language ID */ + uint_8 const ** lang_desc; /* Language Descriptor String */ + uint_8 const * lang_desc_size; /* Language Descriptor Size */ +} USB_LANGUAGE; + +typedef const struct _USB_ALL_LANGUAGES +{ + /* Pointer to Supported Language String */ + uint_8 const *languages_supported_string; + /* Size of Supported Language String */ + uint_8 const languages_supported_size; + /* Array of Supported Languages */ + USB_LANGUAGE usb_language[USB_MAX_SUPPORTED_INTERFACES]; +}USB_ALL_LANGUAGES; + +typedef const struct _USB_ENDPOINTS +{ + /* Number of non control Endpoints */ + uint_8 count; + /* Array of Endpoints Structures */ + USB_EP_STRUCT ep[CDC_DESC_ENDPOINT_COUNT]; +}USB_ENDPOINTS; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_Desc_Get_Descriptor( + uint_8 controller_ID, + uint_8 type, + uint_8 str_num, + uint_16 index, + uint_8_ptr *descriptor, + USB_PACKET_SIZE *size); + +extern uint_8 USB_Desc_Get_Interface( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr alt_interface); + + +extern uint_8 USB_Desc_Set_Interface( + uint_8 controller_ID, + uint_8 interface, + uint_8 alt_interface); + +extern boolean USB_Desc_Valid_Configation( + uint_8 controller_ID, + uint_16 config_val); + +extern boolean USB_Desc_Valid_Interface( + uint_8 controller_ID, + uint_8 interface); + +extern boolean USB_Desc_Remote_Wakeup(uint_8 controller_ID); + +extern void* USB_Desc_Get_Endpoints(uint_8 controller_ID); + +extern uint_8 USB_Desc_Get_Line_Coding( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *coding_data); + +extern uint_8 USB_Desc_Set_Line_Coding( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *coding_data); + +extern uint_8 USB_Desc_Get_Abstract_State( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Get_Country_Setting( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Set_Abstract_State( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); +extern uint_8 USB_Desc_Set_Country_Setting( + uint_8 controller_ID, + uint_8 interface, + uint_8_ptr *feature_data); + +#endif + + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_devapi.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_devapi.h new file mode 100644 index 0000000..3e5421d --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_devapi.h @@ -0,0 +1,479 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_devapi.h + * + * @author + * + * @version + * + * @date + * + * @brief This file contains S08 USB stack device layer API header function. + * + *****************************************************************************/ + +#ifndef _USB_DEVAPI_H +#define _USB_DEVAPI_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" /* User Defined Data Types */ +#include "hidef.h" /* for EnableInterrupts macro */ +#include "derivative.h" /* include peripheral declarations */ +#include "usb_user_config.h" /* User Configuration File << EST 'user_config.h' conflicts with MQX Lite */ +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H +#define USB_MAX_EP_BUFFER_SIZE (512) +#else +#define USB_MAX_EP_BUFFER_SIZE (255) +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#define USB_MAX_EP_BUFFER_SIZE (512) +#endif +#ifndef CONTROL_ENDPOINT +#define CONTROL_ENDPOINT (0) +#endif + +#define USB_SETUP_PKT_SIZE (8) /* Setup Packet Size */ + +/* Error codes */ +#define USB_OK (0x00) +#define USBERR_ALLOC (0x81) +#define USBERR_BAD_STATUS (0x82) +#define USBERR_CLOSED_SERVICE (0x83) +#define USBERR_OPEN_SERVICE (0x84) +#define USBERR_TRANSFER_IN_PROGRESS (0x85) +#define USBERR_ENDPOINT_STALLED (0x86) +#define USBERR_ALLOC_STATE (0x87) +#define USBERR_DRIVER_INSTALL_FAILED (0x88) +#define USBERR_DRIVER_NOT_INSTALLED (0x89) +#define USBERR_INSTALL_ISR (0x8A) +#define USBERR_INVALID_DEVICE_NUM (0x8B) +#define USBERR_ALLOC_SERVICE (0x8C) +#define USBERR_INIT_FAILED (0x8D) +#define USBERR_SHUTDOWN (0x8E) +#define USBERR_INVALID_PIPE_HANDLE (0x8F) +#define USBERR_OPEN_PIPE_FAILED (0x90) +#define USBERR_INIT_DATA (0x91) +#define USBERR_SRP_REQ_INVALID_STATE (0x92) +#define USBERR_TX_FAILED (0x93) +#define USBERR_RX_FAILED (0x94) +#define USBERR_EP_INIT_FAILED (0x95) +#define USBERR_EP_DEINIT_FAILED (0x96) +#define USBERR_TR_FAILED (0x97) +#define USBERR_BANDWIDTH_ALLOC_FAILED (0x98) +#define USBERR_INVALID_NUM_OF_ENDPOINTS (0x99) +#define USBERR_NOT_SUPPORTED (0x9A) + +#define USBERR_DEVICE_NOT_FOUND (0xC0) +#define USBERR_DEVICE_BUSY (0xC1) +#define USBERR_NO_DEVICE_CLASS (0xC3) +#define USBERR_UNKNOWN_ERROR (0xC4) +#define USBERR_INVALID_BMREQ_TYPE (0xC5) +#define USBERR_GET_MEMORY_FAILED (0xC6) +#define USBERR_INVALID_MEM_TYPE (0xC7) +#define USBERR_NO_DESCRIPTOR (0xC8) +#define USBERR_NULL_CALLBACK (0xC9) +#define USBERR_NO_INTERFACE (0xCA) +#define USBERR_INVALID_CFIG_NUM (0xCB) +#define USBERR_INVALID_ANCHOR (0xCC) +#define USBERR_INVALID_REQ_TYPE (0xCD) + +/* Pipe Types */ +#define USB_CONTROL_PIPE (0x00) +#define USB_ISOCHRONOUS_PIPE (0x01) +#define USB_BULK_PIPE (0x02) +#define USB_INTERRUPT_PIPE (0x03) + +/* Device States */ +#define USB_STATE_UNKNOWN (0xff) +#define USB_STATE_PENDING_ADDRESS (0x04) +#define USB_STATE_POWERED (0x03) +#define USB_STATE_DEFAULT (0x02) +#define USB_STATE_ADDRESS (0x01) +#define USB_STATE_CONFIG (0x00) +#define USB_STATE_SUSPEND (0x80) + +/* Get_Status Request information for DEVICE */ +#define USB_SELF_POWERED (0x01) +#define USB_REMOTE_WAKEUP (0x02) + +/* Get_Status Request information for OTG (WINDEX = 0xF000) */ +#ifdef OTG_BUILD +#define USB_OTG_HOST_REQUEST_FLAG (0x01) +#endif + +/* Bus Control values */ +#define USB_NO_OPERATION (0x00) +#define USB_ASSERT_BUS_RESET (0x01) +#define USB_DEASSERT_BUS_RESET (0x02) +#define USB_ASSERT_RESUME (0x03) +#define USB_DEASSERT_RESUME (0x04) +#define USB_SUSPEND_SOF (0x05) +#define USB_RESUME_SOF (0x06) + +/* possible values of Status */ +#define USB_STATUS_IDLE (0) +#define USB_STATUS_TRANSFER_ACCEPTED (6) +#define USB_STATUS_TRANSFER_PENDING (2) +#define USB_STATUS_TRANSFER_IN_PROGRESS (3) +#define USB_STATUS_ERROR (4) +#define USB_STATUS_DISABLED (5) +#define USB_STATUS_STALLED (1) +#define USB_STATUS_TRANSFER_QUEUED (7) + +#define USB_STATUS_UNKNOWN (0xFF) + +#define USB_CONTROL_ENDPOINT (0) + +#define USB_RECV (0) +#define USB_SEND (1) + +#define USB_DEVICE_DONT_ZERO_TERMINATE (0x1) + +#define USB_SETUP_DATA_XFER_DIRECTION (0x80) + +#define USB_SPEED_FULL (0) +#define USB_SPEED_LOW (1) +#define USB_SPEED_HIGH (2) + +#define USB_MAX_PKTS_PER_UFRAME (0x6) + +#define USB_TEST_MODE_TEST_PACKET (0x0400) + +/* Available service types */ +/* Services 0 through 15 are reserved for endpoints */ +#define USB_SERVICE_EP0 (0x00) +#define USB_SERVICE_EP1 (0x01) +#define USB_SERVICE_EP2 (0x02) +#define USB_SERVICE_EP3 (0x03) +#define USB_SERVICE_EP4 (0x04) +#define USB_SERVICE_EP5 (0x05) +#define USB_SERVICE_EP6 (0x06) +#define USB_SERVICE_EP7 (0x07) +#define USB_SERVICE_EP8 (0x08) +#define USB_SERVICE_EP9 (0x09) +#define USB_SERVICE_EP10 (0x0a) +#define USB_SERVICE_EP11 (0x0b) +#define USB_SERVICE_EP12 (0x0c) +#define USB_SERVICE_EP13 (0x0d) +#define USB_SERVICE_EP14 (0x0e) +#define USB_SERVICE_EP15 (0x0f) + +#define USB_SERVICE_BUS_RESET (0x10) +#define USB_SERVICE_SUSPEND (0x11) +#define USB_SERVICE_SOF (0x12) +#define USB_SERVICE_RESUME (0x13) +#define USB_SERVICE_SLEEP (0x14) +#define USB_SERVICE_SPEED_DETECTION (0x15) +#define USB_SERVICE_ERROR (0x16) +#define USB_SERVICE_STALL (0x17) +#define USB_SERVICE_MAX (0x18) + +#if 0 /* << EST */ +#if (defined(_MCF51JM128_H) ||defined(_MCF51MM256_H) || (defined _MCF51JE256_H)) + #define USB_SERVICE_MAX_EP USB_SERVICE_EP15 +#else + #ifdef DOUBLE_BUFFERING_USED + #define USB_SERVICE_MAX_EP USB_SERVICE_EP6 + #else + #define USB_SERVICE_MAX_EP USB_SERVICE_EP4 + #endif +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#ifdef DOUBLE_BUFFERING_USED + #define USB_SERVICE_MAX_EP USB_SERVICE_EP6 +#else + #define USB_SERVICE_MAX_EP USB_SERVICE_EP4 +#endif +#endif + +/* Informational Request/Set Types */ +/* component parameter in USB_Device_Get/Set_Status */ +#define USB_COMPONENT_DIRECTION_SHIFT (7) +#define USB_COMPONENT_DIRECTION_MASK (0x01) +#define USB_STATUS_DEVICE_STATE (0x01) +#define USB_STATUS_INTERFACE (0x02) +#define USB_STATUS_ADDRESS (0x03) +#define USB_STATUS_CURRENT_CONFIG (0x04) +#define USB_STATUS_SOF_COUNT (0x05) +#define USB_STATUS_DEVICE (0x06) + +// Endpoint attributes +#define EP_TRANSFER_TYPE_CONTROL (0x0<<0) +#define EP_TRANSFER_TYPE_ISOCHRONOUS (0x1<<0) +#define EP_TRANSFER_TYPE_BULK (0x2<<0) +#define EP_TRANSFER_TYPE_INTERRUPT (0x3<<0) + +/* Standard Request Code */ +#define GET_STATUS 0x0 +#define CLEAR_FEATURE 0x1 +#define SET_FEATURE 0x3 +#define SET_ADDRESS 0x5 +#define GET_DESCRIPTOR 0x6 +#define SET_DESCRIPTOR 0x7 +#define GET_CONFIGURATION 0x8 +#define SET_CONFIGURATION 0x9 +#define GET_INTERFACE 0xA +#define SET_INTERFACE 0xB +#define SYNCH_FRAME 0xC + +#ifdef OTG_BUILD + #define USB_STATUS_OTG (0x07) + #define USB_STATUS_TEST_MODE (0x08) +#else + #define USB_STATUS_TEST_MODE (0x07) +#endif + +#define USB_STATUS_ENDPOINT (0x10) +#define USB_STATUS_ENDPOINT_NUMBER_MASK (0x0F) + +#define UNINITIALISED_VAL (0xffffffff) + +#if 0 /* << EST */ +#if (defined MCU_MK40N512VMD100) || (defined MCU_MK53N512CMD100) || (defined MCU_MK60N512VMD100) || (defined MCU_MK70F12) + #define USB_DEVICE_ASSERT_RESUME() USB0_CTL |= USB_CTL_RESUME_MASK; + #define USB_DEVICE_DEASSERT_RESUME() USB0_CTL &= ~USB_CTL_RESUME_MASK; +#elif (defined _MC9S08JE128_H) || (defined _MC9S08JM16_H) || defined(_MC9S08JM60_H) || (defined _MC9S08JS16_H) || (defined _MC9S08MM128_H) + #define USB_DEVICE_ASSERT_RESUME() CTL_CRESUME = 1; + #define USB_DEVICE_DEASSERT_RESUME() CTL_CRESUME = 0; +#elif (defined _MCF51JE256_H) || (defined MCU_mcf51jf128) || defined(_MCF51MM256_H) + #define USB_DEVICE_ASSERT_RESUME() USBTRC0_USBRESMEN = 1; + #define USB_DEVICE_DEASSERT_RESUME() USBTRC0_USBRESMEN = 0; +#elif (defined __MCF52221_H__) || defined(__MCF52259_H__) + #define USB_DEVICE_ASSERT_RESUME() CTL |= MCF_USB_OTG_CTL_RESUME; + #define USB_DEVICE_DEASSERT_RESUME() CTL &= ~MCF_USB_OTG_CTL_RESUME; +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#endif + +#define USB_PROCESS_PENDING() ((gu8ProcessPendingFlag != 0) || (gtUSBEPEventFlags != 0)) + + +/****************************************************************************** + * Types + *****************************************************************************/ +typedef void _PTR_ _usb_device_handle; +typedef uint_8 T_EP_BITFIELD; + +#if 0 /* << EST */ +#if !(defined _MC9S08JE128_H) && !(defined _MC9S08JM16_H) && !defined(_MC9S08JM60_H) && !(defined _MC9S08JS16_H) && !(defined _MC9S08MM128_H) +#pragma pack (1) /* Enforce 1 byte struct alignment */ +#endif +#else +#ifndef __HIWARE__ +/* << EST pushing current packing */ +#pragma pack(push) +#pragma pack(1) /* Enforce 1 byte struct alignment */ +#endif +#endif + +#ifdef __MK_xxx_H__ + #if (defined(__CWCC__) || defined(__GNUC__)) + #define ALIGN __attribute__ ((packed)) + #elif((defined __IAR_SYSTEMS_ICC__) || (defined __CC_ARM)) + #define ALIGN + #else + #define ALIGN + #endif +#else + #define ALIGN +#endif + +typedef struct _USB_DEV_EVENT_STRUCT +{ + uint_8 controller_ID; /* controller ID */ + uint_8 ep_num; + boolean setup; /* is setup packet */ + boolean direction; /* direction of endpoint */ + uint_8* buffer_ptr; /* pointer to buffer */ + uint_8 errors; /* Any errors */ + USB_PACKET_SIZE len; /* buffer size of endpoint */ +}ALIGN USB_DEV_EVENT_STRUCT, *PTR_USB_DEV_EVENT_STRUCT; + +// Same endpoint can have multiple function assignments in g_usb_CB, depending on user input +#ifndef MULTIPLE_DEVICES + typedef void(_CODE_PTR_ const USB_SERVICE_CALLBACK)(PTR_USB_DEV_EVENT_STRUCT); +#else + typedef void(_CODE_PTR_ USB_SERVICE_CALLBACK)(PTR_USB_DEV_EVENT_STRUCT); +#endif + +typedef struct _USB_EP_STRUCT +{ + uint_8 ep_num; /* endpoint number */ + uint_8 type; /* type of endpoint */ + uint_8 direction; /* direction of endpoint */ + USB_PACKET_SIZE size ALIGN; /* buffer size of endpoint */ +}ALIGN USB_EP_STRUCT, *USB_EP_STRUCT_PTR; + +#if (defined(__CWCC__))/*||defined(__GNUC__))*/ /* << EST: that pragma does not exist for gcc */ + #pragma options align = reset +#elif defined(__GNUC__) /* << EST */ +/* << EST restoring previous packing */ +#pragma pack(pop) +#elif defined(__IAR_SYSTEMS_ICC__) || defined(__CC_ARM) + #pragma pack() +#endif + + +extern volatile uint_8 gu8ProcessPendingFlag; +extern volatile T_EP_BITFIELD gtUSBEPEventFlags; + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 _usb_device_init ( + uint_8 device_number, + _usb_device_handle _PTR_ handle, + uint_8 number_of_endpoints, + uint_8 bVregEn +); + +extern uint_8 _usb_device_deinit(void); + +extern uint_8 _usb_device_init_endpoint( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_16 max_packet_size, + uint_8 direction, + uint_8 endpoint_type, + uint_8 flag +); + +extern uint_8 _usb_device_cancel_transfer ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern uint_8 _usb_device_deinit_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern uint_8 _usb_device_recv_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uchar_ptr buffer_ptr, + uint_32 size +); + +extern uint_8 _usb_device_send_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uchar_ptr buffer_ptr, + uint_32 size +); + +extern uint_8 _usb_device_get_send_buffer ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 ep_num, /* [IN] Endpoint number */ + uint_8_ptr *buff_ptr, /* [OUT] Buffer for IN endpoint */ + USB_PACKET_SIZE *size /* [OUT] Size of IN endpoint */ +); + +extern void _usb_device_shutdown ( + _usb_device_handle handle +); + +extern void _usb_device_stall_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_unstall_endpoint ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_read_setup_data ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8_ptr buffer_ptr +); + +extern uint_8 _usb_device_get_status ( + _usb_device_handle handle, + uint_8 component, + uint_8_ptr status +); + +extern uint_8 _usb_device_set_status ( + _usb_device_handle handle, + uint_8 component, + uint_8 setting +); + +extern void _usb_device_clear_data0_endpoint( + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_assert_resume ( + _usb_device_handle handle +); + +extern uint_8 _usb_device_register_service ( + uint_8 controller_ID, + uint_8 type, + USB_SERVICE_CALLBACK service +); + +extern uint_8 _usb_device_unregister_service ( + _usb_device_handle handle, + uint_8 event_endpoint +); + +extern uint_8 _usb_device_get_transfer_status ( + _usb_device_handle handle, + uint_8 endpoint_number, + uint_8 direction +); + +extern void _usb_device_set_address ( + _usb_device_handle handle, + uint_8 address +); + +extern uint_8 USB_Device_Call_Service( + uint_8 type, + PTR_USB_DEV_EVENT_STRUCT event +); + +extern void USB_Engine(void); + +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_driver.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_driver.c new file mode 100644 index 0000000..1dbc7ba --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_driver.c @@ -0,0 +1,636 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_driver.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains S08 USB stack device layer implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "usb_devapi.h" /* USB Device Layer API Header File */ +#include "usb_dciapi.h" /* USB Controller API Header File */ +#ifdef _MK_xxx_H_ + #include "usb_dci_kinetis.h" +#endif +#ifndef MULTIPLE_DEVICES + #include "USB_Config.h" +#endif + +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ + + +/**************************************************************************** + * Global Variables + ****************************************************************************/ +extern void USB_Control_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Reset_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Sof_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Resume_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Suspend_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Error_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_Stall_Service (PTR_USB_DEV_EVENT_STRUCT event ); +extern void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event); + +/* Array of USB Service pointers */ +#ifdef MULTIPLE_DEVICES + static USB_SERVICE_CALLBACK g_usb_CB[USB_SERVICE_MAX]; +#else + static USB_SERVICE_CALLBACK g_usb_CB[USB_SERVICE_MAX] = { + USB_EP0_CALLBACK, + USB_EP1_CALLBACK, + USB_EP2_CALLBACK, + USB_EP3_CALLBACK, + USB_EP4_CALLBACK, + USB_EP5_CALLBACK, + USB_EP6_CALLBACK, + USB_EP7_CALLBACK, + USB_EP8_CALLBACK, + USB_EP9_CALLBACK, + USB_EP10_CALLBACK, + USB_EP11_CALLBACK, + USB_EP12_CALLBACK, + USB_EP13_CALLBACK, + USB_EP14_CALLBACK, + USB_EP15_CALLBACK, + USB_BUS_RESET_CALLBACK, + USB_SUSPEND_CALLBACK, + USB_SOF_CALLBACK, + USB_RESUME_CALLBACK, + USB_SLEEP_CALLBACK, + USB_SPEED_DETECTION_CALLBACK, + USB_ERROR_CALLBACK, + USB_STALL_CALLBACK +}; +#endif +/* Array of USB Component Status */ +/* Test mode is the last service */ +static uint_8 g_usb_component_status[USB_STATUS_TEST_MODE]; +/* Array of USB Endpoint Status */ +static uint_8 g_usb_ep_status[MAX_SUPPORTED_ENDPOINTS]; +/* Current un-initialized non CONTROL Endpoint */ +static uint_8 g_EPn=0; +/* Maximum number of Non CONTROL Endpoint required by upper layer */ +static uint_8 g_EPn_max=0; + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes - None + *****************************************************************************/ +static void USB_Device_Init_Params(void); + +/***************************************************************************** + * Local Variables - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions + *****************************************************************************/ +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#endif +/***************************************************************************** + * Global Functions + *****************************************************************************/ +extern uint_8 USB_DCI_Init ( + uint_8 controller_ID, + uint_8 bVregEn +); +extern uint_8 USB_DCI_DeInit(void); + +/**************************************************************************//*! + * + * @name USB_Device_Init_Params + * + * @brief The function initializes the Device Layer Structures + * + * @param None + * + * @return None + * + ****************************************************************************** + * Initializes USB Device Layer Structures + *****************************************************************************/ +static void USB_Device_Init_Params(void) +{ + uint_8 loop_index=0; + + g_EPn= g_EPn_max; /* 1 control endpoint */ + + /* + Initialize USB_STATUS_DEVICE_STATE, USB_STATUS_INTERFACE, + USB_STATUS_ADDRESS, USB_STATUS_CURRENT_CONFIG, USB_STATUS_SOF_COUNT + and USB_STATUS_DEVICE to USB_STATUS_UNKNOWN + */ + for(loop_index = 0; loop_index < USB_STATUS_TEST_MODE; loop_index++) + { + #ifdef OTG_BUILD + if(loop_index != (USB_STATUS_OTG-1)) /* Do not initialize the OTG status with 0xFFFF */ + #endif + { + g_usb_component_status[loop_index] = USB_STATUS_UNKNOWN; + } + } + + /* Initialize status of All Endpoints to USB_STATUS_DISABLED */ + for(loop_index = 0; loop_index < MAX_SUPPORTED_ENDPOINTS; loop_index++) + { + g_usb_ep_status[loop_index] = USB_STATUS_DISABLED; + } +} + +/***************************************************************************** + * Global Functions + *****************************************************************************/ + + +/**************************************************************************//*! + * + * @name _usb_device_init + * + * @brief The function initializes the Device and Controller layer + * + * @param device_number : USB Device controller to initialize + * @param handle : pointer to USB Device handle + * @param number_of_endpoints : Endpoint count of the application + * + * @return status + * USB_OK : When Successfull + * USBERR_INVALID_NUM_OF_ENDPOINTS : When endpoints > max Supported + ****************************************************************************** + * This function initializes the Device layer and the Controller layer of the + * S08 USB stack. It initializes the variables used for this layer and then + * calls the controller layer initialize function + *****************************************************************************/ +uint_8 _usb_device_init ( + uint_8 device_number, /* [IN] USB Device controller to initialize */ + _usb_device_handle _PTR_ handle, /* [IN] Pointer to USB Device handle */ + uint_8 number_of_endpoints, /* [IN] Number of endpoints to initialize */ + uint_8 bVregEn /* Enables or disables internal regulator */ +) +{ + UNUSED(handle); + + /* validate endpoints param */ + if((number_of_endpoints > MAX_SUPPORTED_ENDPOINTS) || + (number_of_endpoints < MIN_SUPPORTED_ENDPOINTS)) + { + return USBERR_INVALID_NUM_OF_ENDPOINTS; + } + + /* init variables */ + g_EPn_max = (uint_8)(number_of_endpoints - 1); + + USB_Device_Init_Params(); + +#ifdef MULTIPLE_DEVICES + /* Initialize all services to null value */ + Clear_Mem((uint_8_ptr)g_usb_CB, + (uint_32)(sizeof(USB_SERVICE_CALLBACK) * USB_SERVICE_MAX), (uint_8)0); +#endif + /* Call controller layer initialization function */ + return USB_DCI_Init(device_number, bVregEn); + +} + +/**************************************************************************//*! + * + * @name _usb_device_deinit + * + * @brief The function de-initializes the Device and Controller layer + * + * @return status + * USB_OK : When Successfull + * USBERR_INVALID_NUM_OF_ENDPOINTS : When endpoints > max Supported + ****************************************************************************** + * This function de-initializes the Device layer and the Controller layer + *****************************************************************************/ +uint_8 _usb_device_deinit(void) +{ + g_EPn_max = 0; + /* Call controller layer de-initialization function */ + return USB_DCI_DeInit(); +} + +/**************************************************************************//*! + * + * @name _usb_device_init_endpoint + * + * @brief The function initializes the endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param max_packet_size : Maximum packet size (in bytes) for the endpoint + * @param direction : Direction of transfer + * @param endpoint_type : Type of endpoint + * @param flag : Zero termination flag + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_INIT_FAILED : When endpoints > max Supported + ****************************************************************************** + * + * This function initializes an endpoint the Device layer and the Controller + * layer in the S08 USB stack. It validate whether all endpoints have already + * been initialized or not and then calls the controller layer endpoint + * initialize function + * + *****************************************************************************/ +uint_8 _usb_device_init_endpoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number*/ + uint_16 max_packet_size, /* [IN] Maximum packet size (in bytes) for the endpoint */ + uint_8 direction, /* [IN] Direction of transfer */ + uint_8 endpoint_type, /* [IN] Type of endpoint */ + uint_8 flag /* [IN] Zero termination flag */ +) +{ + USB_EP_STRUCT ep_str; + + uint_8 status = USB_OK; + + /* check if all endpoint have already been initialised */ + if((g_EPn == 0) && (endpoint_number != CONTROL_ENDPOINT)) + { + return USBERR_EP_INIT_FAILED; + } + + ep_str.direction = direction; + ep_str.ep_num = endpoint_number; + +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H + ep_str.size = max_packet_size; +#else + ep_str.size = (char)max_packet_size; +#endif +#else +/* device is Kinetis K22FN120 << EST */ + ep_str.size = max_packet_size; +#endif + + ep_str.type = endpoint_type; + + /* call controller layer for initiazation */ + status = USB_DCI_Init_EndPoint(*((uint_8*)handle), &ep_str, flag); + + /* if endpoint successfully initialised update counter */ + if ((ep_str.ep_num != CONTROL_ENDPOINT) && (status == USB_OK)) + { + g_EPn--; + } + + return status; +} + + +/**************************************************************************//*! + * + * @name _usb_device_deinit_endpoint + * + * @brief The function de-initializes the endpoint + * + * @param handle : USB Device handle + * @param endpoint_number : Endpoint number + * @param direction : Endpoint direction + * + * @return status + * USB_OK : When Successfull + * USBERR_EP_DEINIT_FAILED : When endpoints > max Supported + ****************************************************************************** + * + * This function deinitializes an endpoint the Device layer and the Controller + * layer in the S08 USB stack. It validate whether all endpoints have already + * been deinitialized or not and then calls the controller layer endpoint + * deinitialize function + * + *****************************************************************************/ +uint_8 _usb_device_deinit_endpoint ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 endpoint_number, /* [IN] Endpoint number */ + uint_8 direction /* [IN] Direction */ +) +{ + uint_8 status=USB_OK; + + /* check if all endpoint have already been initialised */ + if((g_EPn == g_EPn_max) && (endpoint_number != CONTROL_ENDPOINT)) + { + return USBERR_EP_DEINIT_FAILED; + } + + /* call controller layer for initiazation */ + status = USB_DCI_Deinit_EndPoint(*((uint_8*)handle), endpoint_number, direction); + + /* if endpoint successfully deinitialised update counter */ + if ((endpoint_number != CONTROL_ENDPOINT) && (status == USB_OK)) + { + g_EPn++; + } + + return status; +} + +/**************************************************************************//*! + * + * @name _usb_device_get_status + * + * @brief The function retrieves various endpoint as well as USB component status + * + * @param handle : USB Device handle + * @param component : USB component + * @param status : Pointer to 16 bit return value + * + * @return status + * USB_OK : When Successfull + * USBERR_BAD_STATUS : When error + * + ****************************************************************************** + * This function retrieves the endpoint as well USB component status which is + * stored by calling USB_Device_Set_Status. This function can be called by Ap- + * plication as well as the DCI layer. + *****************************************************************************/ +uint_8 _usb_device_get_status ( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 component, /* [IN] USB component */ + uint_8_ptr status /* [OUT] Pointer to 16 bit return value */ +) +{ + /* get the endpoint number from component input variable */ + uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK); + UNUSED (handle) + + if((component <= USB_STATUS_TEST_MODE) && + (component >= USB_STATUS_DEVICE_STATE)) + { + /* Get the corresponding component status + -1 as components start from 1 */ + *status = g_usb_component_status[component-1]; + } + else if ((component & USB_STATUS_ENDPOINT) && + (ep_num < MAX_SUPPORTED_ENDPOINTS)) + { + /* Get the corresponding endpoint status */ + *status = g_usb_ep_status[ep_num]; + } + else + { + return USBERR_BAD_STATUS; + } + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_device_set_status + * + * @brief The function saves status of endpoints as well as USB components. + * + * @param handle : USB Device handle + * @param component : USB component + * @param setting : Value to be set + * + * @return status + * USB_OK : When Successfull + * USBERR_BAD_STATUS : When error + * + ****************************************************************************** + * This function sets the endpoint as well USB component status which can be + * retrieved by calling _usb_device_get_status. This function can be called by + * Application as well as the DCI layer. + *****************************************************************************/ +uint_8 _usb_device_set_status( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 component, /* [IN] USB Component status to set */ + uint_8 setting /* [IN] Status to set */ +) +{ + /* get the endpoint number from component input variable */ + uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK); + UNUSED (handle) + + if((component <= USB_STATUS_TEST_MODE) && + (component >= USB_STATUS_DEVICE_STATE)) + { + /* + Set the corresponding component setting + -1 as components start from 1 + */ + g_usb_component_status[component-1] = setting; + } + else if ((component & USB_STATUS_ENDPOINT) && + (ep_num < MAX_SUPPORTED_ENDPOINTS)) + { + uint_8 direction = + (uint_8)((component >> USB_COMPONENT_DIRECTION_SHIFT) & + USB_COMPONENT_DIRECTION_MASK); + /* HALT Endpoint */ + if(setting == USB_STATUS_STALLED) + { + _usb_device_stall_endpoint(handle, ep_num, direction); + } + else if((setting == USB_STATUS_IDLE) && + (g_usb_ep_status[ep_num] == USB_STATUS_STALLED)) + { + _usb_device_unstall_endpoint(handle, ep_num, direction); + + if(ep_num == CONTROL_ENDPOINT) + { + direction = (uint_8)((direction == USB_SEND)? + (USB_RECV):(USB_SEND)); + _usb_device_unstall_endpoint(handle, ep_num, direction); + } + } + /* Set the corresponding endpoint setting */ + g_usb_ep_status[ep_num] = setting; + } + else + { + return USBERR_BAD_STATUS; + } + return USB_OK; +} + +/**************************************************************************//*! + * + * @name _usb_device_register_service + * + * @brief The function registers a callback function from the Application layer + * + * @param controller_ID : Controller ID + * @param type : event type or endpoint number + * @param service : callback function pointer + * + * @return status + * USB_OK : When Successfull + * USBERR_ALLOC_SERVICE : When invalid type or already registered + * + ****************************************************************************** + * This function registers a callback function from the application if it is + * called not already registered so that the registered callback function can + * be if the event of that type occurs + *****************************************************************************/ +uint_8 _usb_device_register_service( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 type, /* [IN] type of event or endpoint + number to service */ + USB_SERVICE_CALLBACK service /* [IN] pointer to callback + function */ +) +{ + UNUSED (controller_ID) + UNUSED (service) +#ifdef MULTIPLE_DEVICES + /* check if the type is valid and callback for the type + is not already registered */ + if(((type <= USB_SERVICE_MAX_EP) || + ((type < USB_SERVICE_MAX) && (type >= USB_SERVICE_BUS_RESET))) && + (g_usb_CB[type] == NULL)) + { + + /* register the callback function */ + g_usb_CB[type] = service; + return USB_OK; + } + else + { + return USBERR_ALLOC_SERVICE; + } +#else + UNUSED(type); + return USB_OK; +#endif + +} + +/**************************************************************************//*! + * + * @name _usb_device_unregister_service + * + * @brief The function unregisters an event or endpoint callback function + * + * @param handle : USB Device handle + * @param event_endpoint : event type or endpoint number + * + * @return status + * USB_OK : When Successfull + * USBERR_UNKNOWN_ERROR : When invalid type or not registered + * + ***************************************************************************** + * This function un registers a callback function which has been previously + * registered by the application layer + *****************************************************************************/ +uint_8 _usb_device_unregister_service( + _usb_device_handle handle, /* [IN] USB Device handle */ + uint_8 event_endpoint /* [IN] Endpoint (0 through 15) or event to service */ +) +{ + UNUSED (handle) + /* check if the type is valid and callback for the type + is already registered */ + if(((event_endpoint <= USB_SERVICE_MAX_EP) || + ((event_endpoint < USB_SERVICE_MAX) && (event_endpoint >= USB_SERVICE_BUS_RESET))) && + (g_usb_CB[event_endpoint] != NULL)) + { +#ifdef MULTIPLE_DEVICES + /* unregister the callback */ + g_usb_CB[event_endpoint] = NULL; +#endif + return USB_OK; + } + else + { + return USBERR_UNKNOWN_ERROR; + } +} + +/**************************************************************************//*! + * + * @name USB_Device_Call_Service + * + * @brief The function is a device layer event handler + * + * @param type : Type of service or endpoint + * @param event : Pointer to event structure + * + * @return status + * USB_OK : Always + * + ***************************************************************************** + * + * This function calls the registered service callback function of the applic- + * ation layer based on the type of event received. This function is called + * from the DCI layer. + * + *****************************************************************************/ +uint_8 USB_Device_Call_Service( + uint_8 type, /* [IN] Type of service or endpoint */ + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to event structure */ +) +{ + + if(type == USB_SERVICE_BUS_RESET) + { /* if it is an reset interrupt then reset all status structures */ + USB_Device_Init_Params(); + } + + /* check if the callback is registered or not */ + if(g_usb_CB[type] != NULL) + { + /* call the callback function */ + g_usb_CB[type](event); + } + + return USB_OK; +} + +void USB_NULL_CALLBACK (PTR_USB_DEV_EVENT_STRUCT event) +{ + UNUSED(event) + + #if (defined(__CWCC__) || defined(__IAR_SYSTEMS_ICC__)) + asm("nop"); + #elif defined(__GNUC__) + __asm("nop"); + #elif defined (__CC_ARM) + __nop(); + #endif +} + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.c new file mode 100644 index 0000000..98c19b7 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.c @@ -0,0 +1,1193 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_framework.c + * + * @author + * + * @version + * + * @date + * + * @brief The file contains USB stack framework module implementation. + * + *****************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" /* Contains User Defined Data Types */ +#include "usb_class.h" /* USB class Header File */ +#include "usb_framework.h" /* USB Framework Header File */ +#include "usb_descriptor.h" /* USB descriptor Header File */ +#if defined(__IAR_SYSTEMS_ICC__) +#include +#endif +#ifdef OTG_BUILD +#include "usb_otg_main.h" /* OTG header file */ +#endif +#include +/***************************************************************************** + * Constant and Macro's + *****************************************************************************/ +/**************************************************************************** + * Global Variables + ****************************************************************************/ +static USB_SETUP_STRUCT g_setup_pkt; + +/*is used to store the value of data which needs to be sent to the USB +host in response to the standard requests.*/ +static uint_16 g_std_framework_data; +/*used to store the address received in Set Address in the standard request.*/ +static uint_8 g_assigned_address; +/* Framework module callback pointer */ +static USB_CLASS_CALLBACK g_framework_callback=NULL; +/* Other Requests Callback pointer */ +static USB_REQ_FUNC g_other_req_callback=NULL; + +#ifdef DELAYED_PROCESSING +static USB_DEV_EVENT_STRUCT g_f_event; +/* initially no pending request */ +static boolean g_control_pending=FALSE; +#endif + +/* << EST: + * Setter and Getter for callback function pointers, so the application can overwrite them + * See https://mcuoneclipse.com/requests/comment-page-5/#comment-86524 + */ +USB_CLASS_CALLBACK USB_Get_Framework_Callback(void) { + return g_framework_callback; +} + +void USB_Set_Framework_Callback(USB_CLASS_CALLBACK callback) { + g_framework_callback = callback; +} + +USB_REQ_FUNC USB_Get_OtherRequest_Callback(void) { + return g_other_req_callback; +} + +void USB_Set_OtherRequest_Callback(USB_REQ_FUNC callback) { + g_other_req_callback = callback; +} +/* << EST end */ + +boolean const g_validate_request[MAX_STRD_REQ][3] = +{ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Get_Status*/ + /* configured state: valid for existing interfaces/endpoints + address state : valid only for interface or endpoint 0 + default state : not specified + */ + {TRUE,TRUE,FALSE}, /* Clear Feature */ + /* configured state: valid only for device in configured state + address state : valid only for device (in address state), + interface and endpoint 0 + default state : not specified + */ + {FALSE,FALSE,FALSE}, /*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ +#ifdef OTG_BUILD + {TRUE,TRUE,TRUE}, /* Set Feature */ + /* configured state: A B-device that supports OTG features + address state : shall be able to accept the SetFeature command + default state : in the Default, Addressed and Configured states + */ +#else + {TRUE,TRUE,FALSE}, /* Set Feature */ + /* configured state: valid only for device in configured state + address state : valid only for interface or endpoint 0 + default state : not specified + */ +#endif + + {FALSE,FALSE,FALSE},/*reserved for future use*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {FALSE,TRUE,TRUE}, /*USB_Strd_Req_Set_Address*/ + /* configured state: not specified + address state : changes to default state if specified addr == 0, + but uses newly specified address + default state : changes to address state if specified addr != 0 + */ + {TRUE,TRUE,TRUE}, /*USB_Strd_Req_Get_Descriptor*/ + /* configured state: valid request + address state : valid request + default state : valid request + */ + {FALSE,FALSE,FALSE}, /*Set Descriptor*/ + /* configured state: request not supported + address state : request not supported + default state : request not supported + */ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Get_Config*/ + /* configured state: bConfiguration Value of current config returned + address state : value zero must be returned + default state : not specified + */ + {TRUE,TRUE,FALSE}, /*USB_Strd_Req_Set_Config*/ + /* configured state: If the specified configuration value is zero, + then the device enters the Address state.If the + specified configuration value matches the + configuration value from a config descriptor, + then that config is selected and the device + remains in the Configured state. Otherwise, the + device responds with a Request Error. + + address state : If the specified configuration value is zero, + then the device remains in the Address state. If + the specified configuration value matches the + configuration value from a configuration + descriptor, then that configuration is selected + and the device enters the Configured state. + Otherwise,response is Request Error. + default state : not specified + */ + {TRUE,FALSE,FALSE}, /*USB_Strd_Req_Get_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {TRUE,FALSE,FALSE}, /*USB_Strd_Req_Set_Interface*/ + /* configured state: valid request + address state : request error + default state : not specified + */ + {TRUE,FALSE,FALSE} /*USB_Strd_Req_Sync_Frame*/ + /* configured state: valid request + address state : request error + default state : not specified + */ +}; +/***************************************************************************** + * Global Functions Prototypes - None + *****************************************************************************/ + +/***************************************************************************** + * Local Types - None + *****************************************************************************/ + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ +void USB_Control_Service (PTR_USB_DEV_EVENT_STRUCT event ); +static void USB_Control_Service_Handler(uint_8 controller_ID, + uint_8 status, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Status(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Feature(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Address(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Assign_Address(uint_8 controller_ID); +static uint_8 USB_Strd_Req_Get_Config(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Config(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Interface(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Set_Interface(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Sync_Frame(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); +static uint_8 USB_Strd_Req_Get_Descriptor(uint_8 controller_ID, + USB_SETUP_STRUCT * setup_packet, + uint_8_ptr *data, + USB_PACKET_SIZE *size); + +#ifdef DELAYED_PROCESSING +static void USB_Control_Service_Callback(PTR_USB_DEV_EVENT_STRUCT event ); +#endif + +/***************************************************************************** + * Local Functions Prototypes + *****************************************************************************/ + +/***************************************************************************** + * Local Variables + *****************************************************************************/ +static uint_8 ext_req_to_host[USB_OUT_PKT_SIZE + USB_SETUP_PKT_SIZE];/* used for extended OUT transactions on + CONTROL ENDPOINT*/ +/***************************************************************************** + * Global Variables + *****************************************************************************/ +USB_REQ_FUNC +#if 0 /* << EST */ +#if ((!defined(_MC9S08MM128_H)) && (!defined(_MC9S08JE128_H))) +const +#endif +#else +/* device is Kinetis K22FN120 << EST */ +const +#endif +g_standard_request[MAX_STRD_REQ] = +{ + USB_Strd_Req_Get_Status, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Feature, + NULL, + USB_Strd_Req_Set_Address, + USB_Strd_Req_Get_Descriptor, + NULL, + USB_Strd_Req_Get_Config, + USB_Strd_Req_Set_Config, + USB_Strd_Req_Get_Interface, + USB_Strd_Req_Set_Interface, + USB_Strd_Req_Sync_Frame +}; + +#if 0 /* << EST */ +#if (defined(_MC9S08MM128_H) || defined(_MC9S08JE128_H)) +#pragma CODE_SEG DEFAULT +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#endif +/**************************************************************************//*! + * + * @name USB_Framework_Init + * + * @brief The function initializes the Class Module + * + * @param controller_ID : Controller ID + * @param class_callback : Class callback pointer + * @param other_req_callback: Other Request Callback + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + ****************************************************************************** + * This function registers the service on the control endpoint + *****************************************************************************/ +uint_8 USB_Framework_Init ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_CLASS_CALLBACK class_callback, /* Class Callback */ + USB_REQ_FUNC other_req_callback /* Other Request Callback */ +) +{ + uint_8 error=USB_OK; + + /* save input parameters */ + g_framework_callback = class_callback; + g_other_req_callback = other_req_callback; + + /* Register CONTROL service */ + error = _usb_device_register_service(controller_ID, USB_SERVICE_EP0, + +#ifdef DELAYED_PROCESSING + USB_Control_Service_Callback +#else + USB_Control_Service +#endif + ); + + return error; +} + +/**************************************************************************//*! + * + * @name USB_Framework_DeInit + * + * @brief The function De-initializes the Class Module + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * Others : Errors + * + ****************************************************************************** + * This function unregisters control service + *****************************************************************************/ +uint_8 USB_Framework_DeInit +( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + uint_8 error; + /* Free framwork_callback */ + g_framework_callback = NULL; + + /* Free other_req_callback */ + g_other_req_callback = NULL; + + /* Unregister CONTROL service */ + error = _usb_device_unregister_service(&controller_ID, USB_SERVICE_EP0); + + /* Return error */ + return error; +} +#ifdef DELAYED_PROCESSING +/**************************************************************************//*! + * + * @name USB_Framework_Periodic_Task + * + * @brief The function is called to respond to any control request + * + * @param None + * + * @return None + * + ****************************************************************************** + * This function checks for any pending requests and handles them if any + *****************************************************************************/ +void USB_Framework_Periodic_Task(void) +{ + /* if control request pending to be completed */ + if(g_control_pending==TRUE) + { + /* handle pending control request */ + USB_Control_Service(&g_f_event); + g_control_pending = FALSE; + } +} +#endif +/**************************************************************************//*! + * + * @name USB_Framework_Reset + * + * @brief The function resets the framework + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK : When Successfull + * + ****************************************************************************** + * This function is used to reset the framework module + *****************************************************************************/ +uint_8 USB_Framework_Reset ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + UNUSED (controller_ID) + return USB_OK; +} + +#ifdef DELAYED_PROCESSING +/**************************************************************************//*! + * + * @name USB_Control_Service_Callback + * + * @brief The function can be used as a callback function to the service. + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * This function saves the event parameters and queues a pending request + *****************************************************************************/ +void USB_Control_Service_Callback ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + /* save the event parameters */ + g_f_event.buffer_ptr = event->buffer_ptr; + g_f_event.controller_ID = event->controller_ID; + g_f_event.ep_num = event->ep_num; + g_f_event.setup = event->setup; + g_f_event.len = event->len; + g_f_event.errors = event->errors; + + /* set the pending request flag */ + g_control_pending = TRUE; + +} +#endif + +/**************************************************************************//*! + * + * @name USB_Control_Service + * + * @brief Called upon a completed endpoint 0 transfer + * + * @param event : Pointer to USB Event Structure + * + * @return None + * + ****************************************************************************** + * This function handles the data sent or received on the control endpoint + *****************************************************************************/ +void USB_Control_Service ( + PTR_USB_DEV_EVENT_STRUCT event /* [IN] Pointer to USB Event Structure */ +) +{ + uint_8 device_state = 0; + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_8_ptr data = NULL; + USB_PACKET_SIZE size; + + /* get the device state */ + (void)_usb_device_get_status(&(event->controller_ID), USB_STATUS_DEVICE_STATE, + &device_state); + + if (event->setup == TRUE) + { + /* get the setup packet */ + (void)memcpy(&g_setup_pkt, event->buffer_ptr, USB_SETUP_PKT_SIZE); + + /* take care of endianess of the 16 bt fields correctly */ + g_setup_pkt.index = BYTE_SWAP16(g_setup_pkt.index); + g_setup_pkt.value = BYTE_SWAP16(g_setup_pkt.value); + g_setup_pkt.length = BYTE_SWAP16(g_setup_pkt.length); + + /* if the request is standard request */ + if ((g_setup_pkt.request_type & USB_REQUEST_CLASS_MASK) == + USB_REQUEST_CLASS_STRD) + { + /* if callback is not NULL */ + if (g_standard_request[g_setup_pkt.request] != NULL) + { + /* if the request is valid in this device state */ + if((device_state < USB_STATE_POWERED) && + (g_validate_request[g_setup_pkt.request][device_state] + ==TRUE)) + { + /* Standard Request function pointers */ + status = g_standard_request[g_setup_pkt.request] + (event->controller_ID, &g_setup_pkt, &data, + (USB_PACKET_SIZE *)&size); + } + } + } + else /* for Class/Vendor requests */ + { + /*get the length from the setup_request*/ + size = (USB_PACKET_SIZE)g_setup_pkt.length; + if (size <= USB_OUT_PKT_SIZE) { + if( (size != 0) && + ((g_setup_pkt.request_type & USB_DATA_DIREC_MASK) == + USB_DATA_TO_DEVICE) ) + { + (void)memcpy(ext_req_to_host, &g_setup_pkt, USB_SETUP_PKT_SIZE); + + /* expecting host to send data (OUT TRANSACTION)*/ + (void)_usb_device_recv_data(&(event->controller_ID), + CONTROL_ENDPOINT, ext_req_to_host+USB_SETUP_PKT_SIZE, + (USB_PACKET_SIZE)(size)); + return; + } + else if(g_other_req_callback != NULL)/*call class/vendor request*/ + { + status = g_other_req_callback(event->controller_ID, + &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + } + } + else + { + /* incase of error Stall endpoint */ + USB_Control_Service_Handler(event->controller_ID, + USBERR_INVALID_REQ_TYPE, &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + return; + } + } + + USB_Control_Service_Handler(event->controller_ID, + status, &g_setup_pkt, &data, (USB_PACKET_SIZE*)&size); + } + /* if its not a setup request */ + else if(device_state == USB_STATE_PENDING_ADDRESS) + { + /* Device state is PENDING_ADDRESS */ + /* Assign the new adddress to the Device */ + (void)USB_Strd_Req_Assign_Address(event->controller_ID); + return; + } + else if( ((g_setup_pkt.request_type & + USB_DATA_DIREC_MASK) == USB_DATA_TO_DEVICE) && + (event->direction == USB_RECV) ) + { + /* execution enters Control Service because of + OUT transaction on CONTROL_ENDPOINT*/ + if(g_other_req_callback != NULL) + { /* class or vendor request */ + size = (USB_PACKET_SIZE)(event->len + USB_SETUP_PKT_SIZE); + status = g_other_req_callback(event->controller_ID, + (USB_SETUP_STRUCT*)(ext_req_to_host), &data, + (USB_PACKET_SIZE*)&size); + } + + USB_Control_Service_Handler(event->controller_ID, + status, &g_setup_pkt, &data, + (USB_PACKET_SIZE*)&size); + } + return; +} + +/**************************************************************************//*! + * + * @name USB_Control_Service_Handler + * + * @brief The function is used to send a response to the Host based. + * + * @param controller_ID : Controller ID + * @param status : Status of request + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return None + * + ****************************************************************************** + * This function sends a response to the data received on the control endpoint. + * the request is decoded in the control service + *****************************************************************************/ +static void USB_Control_Service_Handler ( + uint_8 controller_ID, /* [IN] Controller ID */ + uint_8 status, /* [IN] Device Status */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + if(status == USBERR_INVALID_REQ_TYPE) + { + /* incase of error Stall endpoint */ + (void)_usb_device_set_status(&controller_ID, + (uint_8)(USB_STATUS_ENDPOINT | CONTROL_ENDPOINT | + (USB_SEND << USB_COMPONENT_DIRECTION_SHIFT)), + USB_STATUS_STALLED); + } + else /* Need to send Data to the USB Host */ + { + /* send the data prepared by the handlers.*/ + if(*size > setup_packet->length) + { + *size = (USB_PACKET_SIZE)setup_packet->length; + } + + /* send the data to the host */ + (void)USB_Class_Send_Data(controller_ID, + CONTROL_ENDPOINT, *data, *size); + if((setup_packet->request_type & USB_DATA_DIREC_MASK) == + USB_DATA_TO_HOST) + { /* Request was to Get Data from device */ + /* setup rcv to get status from host */ + (void)_usb_device_recv_data(&controller_ID, + CONTROL_ENDPOINT,NULL,0); + } + + } + return; +} +/*************************************************************************//*! + * + * @name USB_Strd_Req_Get_Status + * + * @brief This function is called in response to Get Status request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is called by the host to know the status of the + * device, the interface and the endpoint + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Status ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8_ptr pu8ConfigDesc = NULL; + uint_16 u16DescSize; + uint_8 interface, endpoint = 0; + uint_8 status; + uint_8 device_state = USB_STATE_POWERED; + + + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE_STATE, &device_state); + + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE) + { + #ifdef OTG_BUILD + if(setup_packet->index == USB_WINDEX_OTG_STATUS_SEL) + { + uint_8 temp; + /* Request for Device */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_OTG, &temp); + g_std_framework_data = (uint_16)temp; + g_std_framework_data &= GET_STATUS_OTG_MASK; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *size = OTG_STATUS_SIZE; + } + else + #endif + { + uint_8 device_state1; + + /* Request for Device */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_state1); + g_std_framework_data = (uint_16)device_state1; + g_std_framework_data &= GET_STATUS_DEVICE_MASK; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + + /* Set Self Powered bit in device state according to configuration */ + status = USB_Desc_Get_Descriptor(controller_ID, USB_CONFIG_DESCRIPTOR, + 0, 0, &pu8ConfigDesc, (USB_PACKET_SIZE *)&u16DescSize); + + if((pu8ConfigDesc[7] & SELF_POWERED) != 0) + { + g_std_framework_data |= BYTE_SWAP16(0x0001); + } + else + { + g_std_framework_data &= BYTE_SWAP16(~0x0001); + } + *size = DEVICE_STATUS_SIZE; + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_INTERFACE) + { + /* Request for Interface */ + interface = (uint_8) setup_packet->index; + if((device_state == USB_STATE_ADDRESS) && (interface > 0)) + { + status = USBERR_INVALID_REQ_TYPE; + } + else + { + /* Interface requests always return 0 */ + g_std_framework_data = 0x0000; + *size = INTERFACE_STATUS_SIZE; + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT) + { + /* Request for Endpoint */ + if((device_state == USB_STATE_ADDRESS) && (endpoint > 0)) + { + status = USBERR_INVALID_REQ_TYPE; + } + else + { + uint_8 device_state2; + endpoint = (uint_8)(((uint_8) setup_packet->index) | + USB_STATUS_ENDPOINT); + status = _usb_device_get_status(&controller_ID, + endpoint, + &device_state2); + g_std_framework_data = (uint_16)device_state2; + /* All other fields except HALT must be zero */ + g_std_framework_data &= 0x0001; /* LSB is for the HALT feature */ + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *size = ENDP_STATUS_SIZE; + } + } + + *data = (uint_8_ptr)&g_std_framework_data; + return status; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Feature + * + * @brief This function is called in response to Clear or Set Feature request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request, used to set/clear a feature on the device + * (device_remote_wakeup and test_mode) or on the endpoint(ep halt) + *****************************************************************************/ +static uint_8 USB_Strd_Req_Feature ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 device_status; + uint_8 set_request; + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_8 epinfo; + uint_8 event; + + UNUSED (data) + + *size=0; + /* Find whether its a clear feature request or a set feature request */ + set_request = (uint_8)((setup_packet->request & USB_SET_REQUEST_MASK) >> 1 ); + + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_DEVICE) + { + /* Request for Device */ + if(set_request == TRUE) + { + /* Standard Feature Selector */ + if((setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP) || (setup_packet->value == DEVICE_FEATURE_TEST_MODE)) + { + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_status); + + if(status == USB_OK) + { + /* Add the request to be set to the device_status */ + device_status |= (uint_16)(1 << (uint_8)setup_packet->value); + + /* Set the status on the device */ + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE, device_status); + } + } + #ifdef OTG_BUILD + /* OTG Feature Selector */ + else if(setup_packet->value == DEVICE_SET_FEATURE_B_HNP_ENABLE) + { + OTG_DESCRIPTOR_PTR_T otg_desc_ptr; + USB_PACKET_SIZE size; + + status = USB_Desc_Get_Descriptor(controller_ID, USB_OTG_DESCRIPTOR,(uint_8)UNINITIALISED_VAL, + (uint_16)UNINITIALISED_VAL,(uint_8_ptr *)&otg_desc_ptr,&size); + if(status == USB_OK) + { + if(otg_desc_ptr->bmAttributes & USB_OTG_HNP_SUPPORT) + { + _usb_otg_hnp_enable(controller_ID, set_request); + } + } + } + #endif + else + { + status = USBERR_INVALID_REQ_TYPE; + } + } + else //(set_request == FALSE) it is a clear feature request + { + if(setup_packet->value == DEVICE_FEATURE_REMOTE_WAKEUP) + { + status = _usb_device_get_status(&controller_ID, USB_STATUS_DEVICE, &device_status); + + if(status == USB_OK) + { + /* Remove the request to be cleared from device_status */ + device_status &= (uint_16)~(1 << (uint_8)setup_packet->value); + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE, device_status); + } + } + else + { + status = USBERR_INVALID_REQ_TYPE; + } + } + } + else if((setup_packet->request_type & USB_REQUEST_SRC_MASK) == USB_REQUEST_SRC_ENDPOINT) + { + /* Request for Endpoint */ + epinfo = (uint_8)(setup_packet->index & 0x00FF); + status = _usb_device_set_status(&controller_ID, (uint_8)(epinfo|USB_STATUS_ENDPOINT), set_request); + + event = (uint_8)(set_request ? USB_APP_EP_STALLED : USB_APP_EP_UNSTALLED); + + if(setup_packet->request == CLEAR_FEATURE) + { + uint_8 epnum = epinfo & 0x0f; + uint_8 dir = (epinfo & 0x80) >> 7; + _usb_device_clear_data0_endpoint(epnum,dir); + event = USB_APP_EP_UNSTALLED; // as far as the application is concerned, this is an UNSTALL. + } + + /* Inform the upper layers of stall/unstall */ + g_framework_callback(controller_ID,event,(void*)&epinfo); + } + return status; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Address + * + * @brief This function is called in response to Set Address request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request, saves the new address in a global variable. this + * address is assigned to the device after this transaction completes + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Address ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + UNUSED (data) + *size=0; + /* update device state */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE, USB_STATE_PENDING_ADDRESS); + + /*store the address from setup_packet into assigned_address*/ + g_assigned_address = (uint_8)setup_packet->value; + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Assign_Address + * + * @brief This function assigns the address to the Device + * + * @param controller_ID : Controller ID + * + * @return status + * USB_OK: Always + * + ****************************************************************************** + * This function assigns the new address and is called (from the control + * service) after the set address transaction completes + *****************************************************************************/ +static uint_8 USB_Strd_Req_Assign_Address ( + uint_8 controller_ID /* [IN] Controller ID */ +) +{ + /* Set Device Address */ + (void)_usb_device_set_address(&controller_ID, g_assigned_address); + + /* Set Device state */ + (void)_usb_device_set_status(&controller_ID, + USB_STATUS_DEVICE_STATE, USB_STATE_ADDRESS); + /* Set Device state */ + (void)_usb_device_set_status(&controller_ID, USB_STATUS_ADDRESS, + g_assigned_address); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Config + * + * @brief This function is called in response to Get Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : Always + * + ****************************************************************************** + * This is a ch9 request and is used to know the currently used configuration + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Config ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 device_status; + + UNUSED(setup_packet) + + *size = CONFIG_SIZE; + (void)_usb_device_get_status(&controller_ID, USB_STATUS_CURRENT_CONFIG, &device_status); + g_std_framework_data = (uint_16)device_status; + g_std_framework_data = BYTE_SWAP16(g_std_framework_data); + *data = (uint_8_ptr)(&g_std_framework_data); + + return USB_OK; +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Config + * + * @brief This function is called in response to Set Config request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used by the host to set the new configuration + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Config ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status = USBERR_INVALID_REQ_TYPE; + uint_16 config_val; + + UNUSED (data) + *size = 0; + status = USB_STATUS_ERROR; + config_val = setup_packet->value; + + if (USB_Desc_Valid_Configation(controller_ID, config_val)) + /*if valid configuration (fn returns boolean value)*/ + { + uint_8 device_state = USB_STATE_CONFIG; + + /* if config_val is 0 */ + if (!config_val) + { + device_state = USB_STATE_ADDRESS ; + } + + status = _usb_device_set_status(&controller_ID, USB_STATUS_DEVICE_STATE, + device_state); + status = _usb_device_set_status(&controller_ID, + USB_STATUS_CURRENT_CONFIG, (uint_8)config_val); + /* + Callback to the app. to let the application know about the new + Configuration + */ + g_framework_callback(controller_ID,USB_APP_CONFIG_CHANGED, + (void *)&config_val); + g_framework_callback(controller_ID,USB_APP_ENUM_COMPLETE, NULL); + } + + return status; + } + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Get_Interface + * + * @brief This function is called in response to Get Interface request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used to know the current interface + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + + /* Request type not for interface */ + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) != USB_REQUEST_SRC_INTERFACE) + { + return USB_STATUS_ERROR; + } + else + { + *size = INTERFACE_SIZE; + status = USB_Desc_Get_Interface(controller_ID,(uint_8)setup_packet->index, + (uint_8_ptr)&g_std_framework_data); + *data = (uint_8_ptr)&g_std_framework_data; + + return status; + } +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Set_Interface + * + * @brief This function is called in response to Set Interface request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : Always + * + ****************************************************************************** + * This is a ch9 request and is used by the host to set the interface + *****************************************************************************/ +static uint_8 USB_Strd_Req_Set_Interface ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + + UNUSED (data); + *size=0; + + /* Request type not for interface */ + if((setup_packet->request_type & USB_REQUEST_SRC_MASK) != USB_REQUEST_SRC_INTERFACE) + { + return USB_STATUS_ERROR; + } + else + { + /* Set Interface and alternate interface from setup_packet */ + status = USB_Desc_Set_Interface(controller_ID,(uint_8)setup_packet->index, + (uint_8)setup_packet->value); + + UNUSED (status); + + return USB_OK; + } +} + +/**************************************************************************//*! + * + * @name USB_Strd_Req_Sync_Frame + * + * @brief This function is called in response to Sync Frame request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This req is used to set and then report an ep's synchronization frame + *****************************************************************************/ +static uint_8 USB_Strd_Req_Sync_Frame ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 status; + uint_8 device_status; + + UNUSED(setup_packet) + *size = FRAME_SIZE; + + /* Get the frame number */ + status = _usb_device_get_status(&controller_ID, USB_STATUS_SOF_COUNT, + &device_status); + g_std_framework_data = (uint_16)device_status; + *data = (uint_8_ptr)&g_std_framework_data; + + return status; +} + + +/**************************************************************************//*! + * + * @name USB_Std_Req_Get_Descriptor + * + * @brief This function is called in response to Get Descriptor request + * + * @param controller_ID : Controller ID + * @param setup_packet : Setup packet received + * @param data : Data to be send back + * @param size : Size to be returned + * + * @return status: + * USB_OK : When Successfull + * Others : When Error + * + ****************************************************************************** + * This is a ch9 request and is used to send the descriptor requested by the + * host + *****************************************************************************/ +static uint_8 USB_Strd_Req_Get_Descriptor ( + uint_8 controller_ID, /* [IN] Controller ID */ + USB_SETUP_STRUCT * setup_packet, /* [IN] Setup packet received */ + uint_8_ptr *data, /* [OUT] Data to be send back */ + USB_PACKET_SIZE *size /* [OUT] Size to be returned */ +) +{ + uint_8 type = USB_uint_16_high(setup_packet->value); + uint_16 index = (uint_16)UNINITIALISED_VAL; + uint_8 str_num = (uint_8)UNINITIALISED_VAL; + uint_8 status; + + /* for string descriptor set the language and string number */ + index = setup_packet->index; + /*g_setup_pkt.lValue*/ + str_num = USB_uint_16_low(setup_packet->value); + + /* Call descriptor class to get descriptor */ + status = USB_Desc_Get_Descriptor(controller_ID, type, str_num, index, data, size); + + return status; +} diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.h new file mode 100644 index 0000000..88fc707 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_framework.h @@ -0,0 +1,166 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file usb_framwork.h + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains USB Framework module API header function. + * + *****************************************************************************/ + +#ifndef _USB_FRAMEWORK_H +#define _USB_FRAMEWORK_H + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include "types.h" +#include "usb_class.h" +#include "usb_descriptor.h" + +/****************************************************************************** + * Constants - None + *****************************************************************************/ + +/****************************************************************************** + * Macro's + *****************************************************************************/ +#define MAX_STRD_REQ (13) /* Max value of standard request */ +/* size of data to be returned for various Get Desc calls */ +#define DEVICE_STATUS_SIZE (2) +#ifdef OTG_BUILD +#define OTG_STATUS_SIZE (2) +#endif +#define INTERFACE_STATUS_SIZE (2) + +#define CONFIG_SIZE (1) +#define INTERFACE_SIZE (1) +#define FRAME_SIZE (2) +#define ENDP_STATUS_SIZE (2) + +#ifdef OTG_BUILD +#define DEVICE_SET_FEATURE_B_HNP_ENABLE (0x0003) /* B HNP enable SET/CLEAR feature value */ +#define DEVICE_SET_FEATURE_A_HNP_SUPPORT (0x0004) /* A HNP support SET/CLEAR feature value */ +#endif + +/* Standard Feature Selectors */ +#define DEVICE_FEATURE_REMOTE_WAKEUP (0x0001) +#define DEVICE_FEATURE_TEST_MODE (0x0002) +#define DEVICE_SET_FEATURE_MASK ((uint_16)((1<<(DEVICE_FEATURE_REMOTE_WAKEUP)) | (1<<(DEVICE_FEATURE_TEST_MODE)))) +#define DEVICE_CLEAR_FEATURE_MASK ((uint_16)(1<<(DEVICE_FEATURE_REMOTE_WAKEUP))) + + + +#define REPORT_DESCRIPTOR_TYPE (0x22) +#define STRING_DESCRIPTOR_TYPE (0x03) + +/* masks and values for provides of Get Desc information */ +#define USB_REQUEST_SRC_MASK (0x03) +#define USB_REQUEST_SRC_DEVICE (0x00) +#define USB_REQUEST_SRC_INTERFACE (0x01) +#define USB_REQUEST_SRC_ENDPOINT (0x02) + +#define USB_SET_REQUEST_MASK (0x02) + +/* wIndex values for GET_Status */ +#ifdef OTG_BUILD +#define USB_WINDEX_OTG_STATUS_SEL (0xF000) +#endif + +/* for transfer direction check */ +#define USB_DATA_TO_HOST (0x80) +#define USB_DATA_TO_DEVICE (0x00) +#define USB_DATA_DIREC_MASK (0x80) + +#define USB_uint_16_low(x) ((uint_8)x) /* lsb byte */ +#define USB_uint_16_high(x) ((uint_8)(x>>8)) /* msb byte */ + +#ifdef CPU_LITTLE_ENDIAN /* << EST: defined by Processor Expert CPU.h for Kinetis devices (but NOT in for SDK 1.x!) */ + #ifndef LITTLE_ENDIAN /* might be defined already on the compiler command line? */ + #define LITTLE_ENDIAN + #endif +#elif defined(__GNUC__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) /* GNU/gcc provides these macros */ + #define LITTLE_ENDIAN +#endif + +#if(defined LITTLE_ENDIAN) +#define BYTE_SWAP16(a) (a) +#else +#define BYTE_SWAP16(a) (uint_16)((((uint_16)(a)&0xFF00)>>8) | \ + (((uint_16)(a)&0x00FF)<<8)) +#endif + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Global Functions + *****************************************************************************/ +extern boolean USB_Frame_Remote_Wakeup(uint_8 controller_ID); + +#define USB_Frame_Remote_Wakeup USB_Desc_Remote_Wakeup + +typedef struct _app_data_struct +{ + uint_8_ptr data_ptr; /* pointer to buffer */ + USB_PACKET_SIZE data_size; /* buffer size of endpoint */ +}APP_DATA_STRUCT; + +/* << EST: + * Setter and Getter for callback function pointers, so the application can overwrite them + */ +USB_CLASS_CALLBACK USB_Get_Framework_Callback(void); + +void USB_Set_Framework_Callback(USB_CLASS_CALLBACK callback); + +USB_REQ_FUNC USB_Get_OtherRequest_Callback(void); + +void USB_Set_OtherRequest_Callback(USB_REQ_FUNC callback); +/* << EST end */ + + +extern uint_8 USB_Framework_Init ( + uint_8 controller_ID, + USB_CLASS_CALLBACK callback, + USB_REQ_FUNC other_req_callback +); + +extern uint_8 USB_Framework_DeInit +( + uint_8 controller_ID +); + +extern uint_8 USB_Framework_Reset ( + uint_8 controller_ID +); +#ifdef DELAYED_PROCESSING +extern void USB_Framework_Periodic_Task(void); +#endif + +#endif + diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_user_config.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_user_config.h new file mode 100644 index 0000000..101178a --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/usb_user_config.h @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2009 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + **************************************************************************//*! + * + * @file usb_user_config.h << EST 'user_config.h' conflicts with MQX Lite + * + * @author + * + * @version + * + * @date May-28-2009 + * + * @brief The file contains User Modifiable Macros for Virtual COM Loopback + * Application + * + *****************************************************************************/ +#if 0 /* << EST */ +#include "derivative.h" + +#if (defined MCU_MK70F12) || (defined __MCF52277_H__) + #define HIGH_SPEED_DEVICE (0) +#else + #define HIGH_SPEED_DEVICE (0) +#endif + +#if (defined MCU_MK20D7) || (defined MCU_MK40D7) + #define MCGOUTCLK_72_MHZ +#endif + +#if ((defined __MK_xxx_H__)||(defined MCU_mcf51jf128)) + #define KEY_PRESS_SIM_TMR_INTERVAL (1000) /* 2s between simulated key press events */ +#else + #ifdef __MCF52277_H__ + #define BUTTON_PRESS_SIMULATION (1) + #define KEY_PRESS_SIM_TMR_INTERVAL (2000) /* 2s between simulated key press events */ + #endif +#endif + +#else +#include "FSL_USB_Stack_Config.h" + +/* device is Kinetis K22FN120 << EST */ +#define HIGH_SPEED_DEVICE (0) + + +#endif +/* + Below two MACROS are required for Virtual COM Loopback + Application to execute +*/ +#define LONG_SEND_TRANSACTION /* support to send large data pkts */ +#define LONG_RECEIVE_TRANSACTION /* support to receive large data pkts */ +#ifndef _MC9S08JS16_H + #define USB_OUT_PKT_SIZE 32 /* Define the maximum data length received from the host */ +#else + #define USB_OUT_PKT_SIZE 16 /* Define the maximum data length received from the host */ +#endif + +/* User Defined MACRO to set number of Timer Objects */ +#define MAX_TIMER_OBJECTS 5 + +#if MAX_TIMER_OBJECTS + /* When Enabled Timer Callback is invoked with an argument */ + #define TIMER_CALLBACK_ARG + #undef TIMER_CALLBACK_ARG +#endif + +#if 0 /* << EST */ +#ifndef _MC9S08JS16_H +#define USB_PACKET_SIZE uint_16 /* support 16/32 bit packet size */ +#else +#define USB_PACKET_SIZE uint_8 /* support 8 bit packet size */ +#endif +#else +/* device is Kinetis K22FN120 << EST */ +#define USB_PACKET_SIZE uint_16 /* support 16/32 bit packet size */ +#endif + +#if 0 /* << EST */ +#ifndef _MCF51JM128_H +/* Use double buffered endpoints 5 & 6. To be only used with S08 cores */ +#define DOUBLE_BUFFERING_USED +#endif +#else +/* device is Kinetis K22FN120 << EST */ +/* Use double buffered endpoints 5 & 6. To be only used with S08 cores */ +#define DOUBLE_BUFFERING_USED +#endif diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.c b/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.c new file mode 100644 index 0000000..b11d074 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.c @@ -0,0 +1,46 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file wdt_kinetis.c + * + * @author + * + * @version + * + * @date + * + * @brief This file contains the implementation of the Watchdog service routines on CFV2 + *****************************************************************************/ + +#include "types.h" /* User Defined Data Types */ +#include "derivative.h" /* include peripheral declarations */ +#include "wdt_kinetis.h" /* own header with public declarations */ + +/*****************************************************************************/ +void Watchdog_Reset(void) +{ +#if defined(MCU_MKL24Z4) || defined(MCU_MKL25Z4) || defined(MCU_MKL26Z4) || defined(MCU_MKL46Z4) + (void)(RCM_SRS0 |= RCM_SRS0_WDOG_MASK); +#else + (void)(WDOG_REFRESH = 0xA602, WDOG_REFRESH = 0xB480); +#endif +} diff --git a/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.h b/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.h new file mode 100644 index 0000000..8a34a08 --- /dev/null +++ b/Projects/tinyK22_OpenPnP_Master/Generated_Code/wdt_kinetis.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * Freescale Semiconductor Inc. + * (c) Copyright 2004-2010 Freescale Semiconductor, Inc. + * ALL RIGHTS RESERVED. + * + ****************************************************************************** + * + * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + **************************************************************************//*! + * + * @file Wdt_kinetis.h + * + * @brief This is the header file for the Watchdog service routines on CFV2 + *****************************************************************************/ + + #ifndef _WDT_KINETIS_ + #define _WDT_KINETIS_ + + /***************************************************************************** + * Public functions + * + ****************************************************************************/ + extern void Watchdog_Reset(void); + + #endif /* _INIT_HW_ */ diff --git a/Projects/tinyK22_OpenPnP_Master/ProcessorExpert.pe b/Projects/tinyK22_OpenPnP_Master/ProcessorExpert.pe index 91b5e51..81e9048 100644 --- a/Projects/tinyK22_OpenPnP_Master/ProcessorExpert.pe +++ b/Projects/tinyK22_OpenPnP_Master/ProcessorExpert.pe @@ -3,7 +3,7 @@
tinyK22_OpenPnP_Master Erich Styger Local - 40 + 41 2018-04-17 Eclipse IDE 1.12.2.RT7_b1550-0615 diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/.gitignore b/Projects/tinyk20_OpenPnP_AutoFeeder/.gitignore index 2833401..09ec1fd 100644 --- a/Projects/tinyk20_OpenPnP_AutoFeeder/.gitignore +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/.gitignore @@ -1,5 +1,5 @@ /Debug/ -/Generated_Code/ +# /Generated_Code/ /.settings/ /Documentation/ *.g_c diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/.gdbinit-FreeRTOS-helpers b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/.gdbinit-FreeRTOS-helpers new file mode 100644 index 0000000..8718d5a --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/.gdbinit-FreeRTOS-helpers @@ -0,0 +1,155 @@ +################################################################################# +# .gdbinit-FreeRTOS-helpers +# +# Created on: 29.03.2013 +# Author: Artem Pisarenko +# +# Helper script providing support for FreeRTOS-aware debugging +# Supported architectures: Cortex-M3 +# Features: +# - showing tasks (handle and name); +# - switching context to specified task from almost any context (excluding system exceptions); +# - restore current running context. +################################################################################# + +# Command "freertos_show_threads" +# Shows tasks table: handle(xTaskHandle) and name +define freertos_show_threads + set $thread_list_size = 0 + set $thread_list_size = uxCurrentNumberOfTasks + if ($thread_list_size == 0) + echo FreeRTOS missing or scheduler isn't started\n + else + set $current_thread = pxCurrentTCB + set $tasks_found = 0 + set $idx = 0 + + set $task_list = pxReadyTasksLists + set $task_list_size = sizeof(pxReadyTasksLists)/sizeof(pxReadyTasksLists[0]) + while ($idx < $task_list_size) + _freertos_show_thread_item $task_list[$idx] + set $idx = $idx + 1 + end + + _freertos_show_thread_item xDelayedTaskList1 + _freertos_show_thread_item xDelayedTaskList2 + _freertos_show_thread_item xPendingReadyList + + set $VAL_dbgFreeRTOSConfig_suspend = dbgFreeRTOSConfig_suspend_value + if ($VAL_dbgFreeRTOSConfig_suspend != 0) + _freertos_show_thread_item xSuspendedTaskList + end + + set $VAL_dbgFreeRTOSConfig_delete = dbgFreeRTOSConfig_delete_value + if ($VAL_dbgFreeRTOSConfig_delete != 0) + _freertos_show_thread_item xTasksWaitingTermination + end + end +end + +# Command "freertos_switch_to_task" +# Switches debugging context to specified task, argument - task handle +define freertos_switch_to_task + set var dbgPendingTaskHandle = $arg0 + set $current_IPSR_val = $xpsr & 0xFF + if (($current_IPSR_val >= 1) && ($current_IPSR_val <= 15)) + echo Switching from system exception context isn't supported + else + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + set $last_PRIMASK_val = $PRIMASK + set $last_SCB_ICSR_val = *((volatile unsigned long *)0xE000ED04) + set $last_SYSPRI2_val = *((volatile unsigned long *)0xE000ED20) + set $last_SCB_CCR_val = *((volatile unsigned long *)0xE000ED14) + set $running_IPSR_val = $current_IPSR_val + set $PRIMASK = 0 + # *(portNVIC_SYSPRI2) &= ~(255 << 16) // temporary increase PendSV priority to highest + set {unsigned int}0xe000ed20 = ($last_SYSPRI2_val & (~(255 << 16))) + # set SCB->CCR NONBASETHRDENA bit (allows processor enter thread mode from at any execution priority level) + set {unsigned int}0xE000ED14 = (1) | $last_SCB_CCR_val + set var dbgPendSVHookState = 1 + end + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + stepi + stepi + # here we get rewound to task + end +end + +# Command "freertos_restore_running_context" +# Restores context of running task +define freertos_restore_running_context + set $VAL_dbgPendSVHookState = dbgPendSVHookState + if ($VAL_dbgPendSVHookState == 0) + echo Current task is RUNNING, ignoring command... + else + set var dbgPendingTaskHandle = (void *)pxCurrentTCB + # *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET + set {unsigned int}0xe000ed04 = 0x10000000 + continue + # here we stuck at "bkpt" instruction just before "bx lr" (in helper's xPortPendSVHandler) + # check what execution mode was in context we started to switch from + if ($running_IPSR_val == 0) + # force returning to thread mode with process stack + set $lr = 0xFFFFFFFD + else + # force returning to handler mode + set $lr = 0xFFFFFFF1 + end + stepi + stepi + # here we get rewound to running task at place we started switching + # restore processor state + set $PRIMASK = $last_PRIMASK_val + set {unsigned int}0xe000ed20 = $last_SYSPRI2_val + set {unsigned int}0xE000ED14 = $last_SCB_CCR_val + if ($last_SCB_ICSR_val & (1 << 28)) + set {unsigned int}0xe000ed04 = 0x10000000 + end + set var dbgPendSVHookState = 0 + end +end + +# Command "show_broken_backtrace" +# Workaround of issue when context is being stuck in the middle of function epilogue (i.e., in vTaskDelay()) +# This solution is applied to following situation only: +### ... function body end +### xxxxxxxx+0: add.w r7, r7, #16 +### xxxxxxxx+4: mov sp, r7 ; <- debug current instruction pointer +### xxxxxxxx+6: pop {r7, pc} +### } +# (Otherwise it will crash !) +define show_broken_backtrace + # cancel effect of xxxxxxxx+4 instruction twice (because we will step it to update eclipse views) + set $r7 = $r7 - 16 - 16 + set $pc = $pc - 4 + stepi +end + + +####################### +# Internal functions +define _freertos_show_thread_item + set $list_thread_count = $arg0.uxNumberOfItems + set $prev_list_elem_ptr = -1 + set $list_elem_ptr = $arg0.xListEnd.pxPrevious + while (($list_thread_count > 0) && ($list_elem_ptr != 0) && ($list_elem_ptr != $prev_list_elem_ptr) && ($tasks_found < $thread_list_size)) + set $threadid = $list_elem_ptr->pvOwner + set $thread_name_str = (*((tskTCB *)$threadid)).pcTaskName + set $tasks_found = $tasks_found + 1 + set $list_thread_count = $list_thread_count - 1 + set $prev_list_elem_ptr = $list_elem_ptr + set $list_elem_ptr = $prev_list_elem_ptr->pxPrevious + if ($threadid == $current_thread) + printf "0x%x\t%s\t\t<---RUNNING\n", $threadid, $thread_name_str + else + printf "0x%x\t%s\n", $threadid, $thread_name_str + end + end +end + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.c new file mode 100644 index 0000000..e0a3922 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.c @@ -0,0 +1,599 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS1 +** Channel : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : 1 +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : 1 +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : 1 +** Input buffer size : 64 +** Output buffer size : 64 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** RxD pin signal : +** Transmitter : Enabled +** TxD : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** TxD pin signal : +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS1_RecvChar(AS1_TComData *Chr); +** SendChar - byte AS1_SendChar(AS1_TComData Chr); +** RecvBlock - byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS1_ClearRxBuf(void); +** ClearTxBuf - byte AS1_ClearTxBuf(void); +** GetCharsInRxBuf - word AS1_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS1_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS1.c +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS1_module AS1 module documentation +** @{ +*/ + +/* MODULE AS1. */ + +#include "AS1.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OVERRUN_ERR 0x01U /* Overrun error flag bit */ +#define FRAMING_ERR 0x02U /* Framing error flag bit */ +#define PARITY_ERR 0x04U /* Parity error flag bit */ +#define CHAR_IN_RX 0x08U /* Char is in RX buffer */ +#define FULL_TX 0x10U /* Full transmit buffer */ +#define RUNINT_FROM_TX 0x20U /* Interrupt is in progress */ +#define FULL_RX 0x40U /* Full receive buffer */ +#define NOISE_ERR 0x80U /* Noise error flag bit */ +#define IDLE_ERR 0x0100U /* Idle character flag bit */ +#define BREAK_ERR 0x0200U /* Break detect */ +#define COMMON_ERR 0x0800U /* Common error of RX */ + +LDD_TDeviceData *ASerialLdd1_DeviceDataPtr; /* Device data pointer */ +static word SerFlag; /* Flags for serial communication */ + /* Bits: 0 - OverRun error */ + /* 1 - Framing error */ + /* 2 - Parity error */ + /* 3 - Char in RX buffer */ + /* 4 - Full TX buffer */ + /* 5 - Running int from TX */ + /* 6 - Full RX buffer */ + /* 7 - Noise error */ + /* 8 - Idle character */ + /* 9 - Break detected */ + /* 10 - Unused */ + /* 11 - Unused */ +static word AS1_InpLen; /* Length of input buffer's content */ +static word InpIndexR; /* Index for reading from input buffer */ +static word InpIndexW; /* Index for writing to input buffer */ +static AS1_TComData InpBuffer[AS1_INP_BUF_SIZE]; /* Input buffer for SCI communication */ +static AS1_TComData BufferRead; /* Input char for SCI communication */ +static word AS1_OutLen; /* Length of output bufer's content */ +static word OutIndexR; /* Index for reading from output buffer */ +static word OutIndexW; /* Index for writing to output buffer */ +static AS1_TComData OutBuffer[AS1_OUT_BUF_SIZE]; /* Output buffer for SCI communication */ + +/* +** =================================================================== +** Method : HWEnDi (component AsynchroSerial) +** +** Description : +** Enables or disables the peripheral(s) associated with the bean. +** The method is called automatically as a part of the Enable and +** Disable methods and several internal methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void HWEnDi(void) +{ + (void)ASerialLdd1_ReceiveBlock(ASerialLdd1_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +/* +** =================================================================== +** Method : AS1_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvChar(AS1_TComData *Chr) +{ + byte Result = ERR_OK; /* Return error code */ + + if (AS1_InpLen > 0x00U) { /* Is number of received chars greater than 0? */ + EnterCritical(); /* Disable global interrupts */ + AS1_InpLen--; /* Decrease number of received chars */ + *Chr = InpBuffer[InpIndexR++]; /* Received char */ + if (InpIndexR >= AS1_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexR = 0x00U; /* Set index to the first item into the receive buffer */ + } + Result = (byte)((SerFlag & (OVERRUN_ERR|COMMON_ERR|FULL_RX))? ERR_COMMON : ERR_OK); + SerFlag &= (word)~(word)(OVERRUN_ERR|COMMON_ERR|FULL_RX|CHAR_IN_RX); /* Clear all errors in the status variable */ + ExitCritical(); /* Enable global interrupts */ + } else { + return ERR_RXEMPTY; /* Receiver is empty */ + } + return Result; /* Return error code */ +} + +/* +** =================================================================== +** Method : AS1_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS1_SendChar(AS1_TComData Chr) +{ + if (AS1_OutLen == AS1_OUT_BUF_SIZE) { /* Is number of chars in buffer is the same as a size of the transmit buffer */ + return ERR_TXFULL; /* If yes then error */ + } + EnterCritical(); /* Disable global interrupts */ + AS1_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = Chr; /* Store char to buffer */ + if (OutIndexW >= AS1_OUT_BUF_SIZE) { /* Is the pointer out of the transmit buffer */ + OutIndexW = 0x00U; /* Set index to first item in the transmit buffer */ + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv) +{ + register word count; /* Number of received chars */ + register byte result = ERR_OK; /* Last error */ + + for (count = 0x00U; count < Size; count++) { + switch (AS1_RecvChar(Ptr++)) { /* Receive data and test the return value*/ + case ERR_RXEMPTY: /* No data in the buffer */ + if (result == ERR_OK) { /* If no receiver error reported */ + result = ERR_RXEMPTY; /* Return info that requested number of data is not available */ + } + *Rcv = count; /* Return number of received chars */ + return result; + case ERR_COMMON: /* Receiver error reported */ + result = ERR_COMMON; /* Return info that an error was detected */ + break; + default: + break; + } + } + *Rcv = count; /* Return number of received chars */ + return result; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd) +{ + word count = 0x00U; /* Number of sent chars */ + AS1_TComData *TmpPtr = Ptr; /* Temporary output buffer pointer */ + + while ((count < Size) && (AS1_OutLen < AS1_OUT_BUF_SIZE)) { /* While there is some char desired to send left and output buffer is not full do */ + EnterCritical(); /* Enter the critical section */ + AS1_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = *TmpPtr++; /* Store char to buffer */ + if (OutIndexW >= AS1_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexW = 0x00U; /* Set index to the first item in the transmit buffer */ + } + count++; /* Increase the count of sent data */ + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Exit the critical section */ + } + *Snd = count; /* Return number of sent chars */ + if (count != Size) { /* Is the number of sent chars less then desired number of chars */ + return ERR_TXFULL; /* If yes then error */ + } + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearRxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS1_InpLen = 0x00U; /* Set number of chars in the transmit buffer to 0 */ + InpIndexW = 0x00U; /* Set index on the first item in the transmit buffer */ + InpIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearTxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS1_OutLen = 0x00U; /* Set number of chars in the receive buffer to 0 */ + OutIndexW = 0x00U; /* Set index on the first item in the receive buffer */ + OutIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS1_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInRxBuf(void) +{ + return AS1_InpLen; /* Return number of chars in receive buffer */ +} + +/* +** =================================================================== +** Method : AS1_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInTxBuf(void) +{ + return AS1_OutLen; /* Return number of chars in the transmitter buffer */ +} + +/* +** =================================================================== +** Method : AS1_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS1_Init(void) +{ + SerFlag = 0x00U; /* Reset flags */ + AS1_InpLen = 0x00U; /* No char in the receive buffer */ + InpIndexR = 0x00U; /* Set index on the first item in the receive buffer */ + InpIndexW = 0x00U; + AS1_OutLen = 0x00U; /* No char in the transmit buffer */ + OutIndexR = 0x00U; /* Set index on the first item in the transmit buffer */ + OutIndexW = 0x00U; + ASerialLdd1_DeviceDataPtr = ASerialLdd1_Init(NULL); /* Calling init method of the inherited component */ + HWEnDi(); /* Enable/disable device according to status flags */ +} + +#define ON_ERROR 0x01U +#define ON_FULL_RX 0x02U +#define ON_RX_CHAR 0x04U +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockReceived(LDD_TUserData *UserDataPtr) +{ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (AS1_InpLen < AS1_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer lower than size of buffer? */ + AS1_InpLen++; /* Increase number of chars in the receive buffer */ + InpBuffer[InpIndexW++] = (AS1_TComData)BufferRead; /* Save received char to the receive buffer */ + if (InpIndexW >= AS1_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexW = 0x00U; /* Set index on the first item into the receive buffer */ + } + } else { + SerFlag |= FULL_RX; /* Set flag "full RX buffer" */ + } + (void)ASerialLdd1_ReceiveBlock(ASerialLdd1_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +#define ON_FREE_TX 0x01U +#define ON_TX_CHAR 0x02U +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockSent(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + OutIndexR++; + if (OutIndexR >= AS1_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexR = 0x00U; /* Set index on the first item into the transmit buffer */ + } + AS1_OutLen--; /* Decrease number of chars in the transmit buffer */ + if (AS1_OutLen != 0U) { /* Is number of bytes in the transmit buffer greater then 0? */ + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd1_SendBlock(ASerialLdd1_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } else { + SerFlag &= (byte)~(RUNINT_FROM_TX); /* Clear "running int from TX" and "full TX buff" flags */ + } +} + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnError(LDD_TUserData *UserDataPtr) +{ + LDD_SERIAL_TError SerialErrorMask; /* Serial error mask variable */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + (void)ASerialLdd1_GetError(ASerialLdd1_DeviceDataPtr, &SerialErrorMask); /* Get error state */ + if (SerialErrorMask != 0U) { + SerFlag |= (((SerialErrorMask & LDD_SERIAL_PARITY_ERROR) != 0U ) ? PARITY_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_NOISE_ERROR) != 0U ) ? NOISE_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_RX_OVERRUN) != 0U ) ? OVERRUN_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_FRAMING_ERROR) != 0U ) ? FRAMING_ERR : 0U); + } +} + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBreak(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + SerFlag |= FRAMING_ERR; /* Set framing error flag */ +} + + +/* END AS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.h new file mode 100644 index 0000000..1d43abc --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS1.h @@ -0,0 +1,417 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS1 +** Channel : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : 1 +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : 1 +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : 1 +** Input buffer size : 64 +** Output buffer size : 64 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** RxD pin signal : +** Transmitter : Enabled +** TxD : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** TxD pin signal : +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS1_RecvChar(AS1_TComData *Chr); +** SendChar - byte AS1_SendChar(AS1_TComData Chr); +** RecvBlock - byte AS1_RecvBlock(AS1_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS1_SendBlock(AS1_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS1_ClearRxBuf(void); +** ClearTxBuf - byte AS1_ClearTxBuf(void); +** GetCharsInRxBuf - word AS1_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS1_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS1.h +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS1_module AS1 module documentation +** @{ +*/ + +#ifndef __AS1 +#define __AS1 + +/* MODULE AS1. */ + +/* Include inherited components */ +#include "ASerialLdd1.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef __BWUserType_AS1_TError +#define __BWUserType_AS1_TError + typedef union { + byte err; + struct { + bool OverRun : 1; /* Overrun error flag */ + bool Framing : 1; /* Framing error flag */ + bool Parity : 1; /* Parity error flag */ + bool RxBufOvf : 1; /* Rx buffer full error flag */ + bool Noise : 1; /* Noise error flag */ + bool Break : 1; /* Break detect */ + bool LINSync : 1; /* LIN synchronization error */ + bool BitError : 1; /* Bit error flag - mismatch to the expected value happened. */ + } errName; +} AS1_TError; /* Error flags. For languages which don't support bit access is byte access only to error flags possible. */ +#endif + +#ifndef __BWUserType_AS1_TComData +#define __BWUserType_AS1_TComData + typedef byte AS1_TComData; /* User type for communication. Size of this type depends on the communication data witdh */ +#endif + +#define AS1_INP_BUF_SIZE 0x40U /* Length of the RX buffer */ + +#define AS1_OUT_BUF_SIZE 0x40U /* Length of the TX buffer */ + +/* +** =================================================================== +** Method : AS1_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvChar(AS1_TComData *Chr); + +/* +** =================================================================== +** Method : AS1_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS1_SendChar(AS1_TComData Chr); + +/* +** =================================================================== +** Method : AS1_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS1_RecvBlock(AS1_TComData *Ptr,word Size,word *Rcv); + +/* +** =================================================================== +** Method : AS1_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS1_SendBlock(AS1_TComData *Ptr,word Size,word *Snd); + +/* +** =================================================================== +** Method : AS1_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearRxBuf(void); + +/* +** =================================================================== +** Method : AS1_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS1_ClearTxBuf(void); + +/* +** =================================================================== +** Method : AS1_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInRxBuf(void); + +/* +** =================================================================== +** Method : AS1_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS1_GetCharsInTxBuf(void); + +/* +** =================================================================== +** Method : AS1_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS1_Init(void); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockReceived(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBlockSent(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnError(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS1_ASerialLdd1_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd1_OnBreak(LDD_TUserData *UserDataPtr); + + +/* END AS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef __AS1 */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.c new file mode 100644 index 0000000..5d124d5 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.c @@ -0,0 +1,599 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 12:58, # CodeGen: 11 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS2 +** Channel : UART2 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART2_RX_TX +** Interrupt RxD priority : 2 +** Interrupt TxD : INT_UART2_RX_TX +** Interrupt TxD priority : 2 +** Interrupt Error : INT_UART2_ERR +** Interrupt Error priority : 2 +** Input buffer size : 64 +** Output buffer size : 128 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** RxD pin signal : UART_SWD_RX +** Transmitter : Enabled +** TxD : PTD3/SPI0_SIN/UART2_TX +** TxD pin signal : UART_SWD_TX +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS2_RecvChar(AS2_TComData *Chr); +** SendChar - byte AS2_SendChar(AS2_TComData Chr); +** RecvBlock - byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS2_ClearRxBuf(void); +** ClearTxBuf - byte AS2_ClearTxBuf(void); +** GetCharsInRxBuf - word AS2_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS2_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS2.c +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS2_module AS2 module documentation +** @{ +*/ + +/* MODULE AS2. */ + +#include "AS2.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OVERRUN_ERR 0x01U /* Overrun error flag bit */ +#define FRAMING_ERR 0x02U /* Framing error flag bit */ +#define PARITY_ERR 0x04U /* Parity error flag bit */ +#define CHAR_IN_RX 0x08U /* Char is in RX buffer */ +#define FULL_TX 0x10U /* Full transmit buffer */ +#define RUNINT_FROM_TX 0x20U /* Interrupt is in progress */ +#define FULL_RX 0x40U /* Full receive buffer */ +#define NOISE_ERR 0x80U /* Noise error flag bit */ +#define IDLE_ERR 0x0100U /* Idle character flag bit */ +#define BREAK_ERR 0x0200U /* Break detect */ +#define COMMON_ERR 0x0800U /* Common error of RX */ + +LDD_TDeviceData *ASerialLdd2_DeviceDataPtr; /* Device data pointer */ +static word SerFlag; /* Flags for serial communication */ + /* Bits: 0 - OverRun error */ + /* 1 - Framing error */ + /* 2 - Parity error */ + /* 3 - Char in RX buffer */ + /* 4 - Full TX buffer */ + /* 5 - Running int from TX */ + /* 6 - Full RX buffer */ + /* 7 - Noise error */ + /* 8 - Idle character */ + /* 9 - Break detected */ + /* 10 - Unused */ + /* 11 - Unused */ +static word AS2_InpLen; /* Length of input buffer's content */ +static word InpIndexR; /* Index for reading from input buffer */ +static word InpIndexW; /* Index for writing to input buffer */ +static AS2_TComData InpBuffer[AS2_INP_BUF_SIZE]; /* Input buffer for SCI communication */ +static AS2_TComData BufferRead; /* Input char for SCI communication */ +static word AS2_OutLen; /* Length of output bufer's content */ +static word OutIndexR; /* Index for reading from output buffer */ +static word OutIndexW; /* Index for writing to output buffer */ +static AS2_TComData OutBuffer[AS2_OUT_BUF_SIZE]; /* Output buffer for SCI communication */ + +/* +** =================================================================== +** Method : HWEnDi (component AsynchroSerial) +** +** Description : +** Enables or disables the peripheral(s) associated with the bean. +** The method is called automatically as a part of the Enable and +** Disable methods and several internal methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void HWEnDi(void) +{ + (void)ASerialLdd2_ReceiveBlock(ASerialLdd2_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +/* +** =================================================================== +** Method : AS2_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvChar(AS2_TComData *Chr) +{ + byte Result = ERR_OK; /* Return error code */ + + if (AS2_InpLen > 0x00U) { /* Is number of received chars greater than 0? */ + EnterCritical(); /* Disable global interrupts */ + AS2_InpLen--; /* Decrease number of received chars */ + *Chr = InpBuffer[InpIndexR++]; /* Received char */ + if (InpIndexR >= AS2_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexR = 0x00U; /* Set index to the first item into the receive buffer */ + } + Result = (byte)((SerFlag & (OVERRUN_ERR|COMMON_ERR|FULL_RX))? ERR_COMMON : ERR_OK); + SerFlag &= (word)~(word)(OVERRUN_ERR|COMMON_ERR|FULL_RX|CHAR_IN_RX); /* Clear all errors in the status variable */ + ExitCritical(); /* Enable global interrupts */ + } else { + return ERR_RXEMPTY; /* Receiver is empty */ + } + return Result; /* Return error code */ +} + +/* +** =================================================================== +** Method : AS2_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS2_SendChar(AS2_TComData Chr) +{ + if (AS2_OutLen == AS2_OUT_BUF_SIZE) { /* Is number of chars in buffer is the same as a size of the transmit buffer */ + return ERR_TXFULL; /* If yes then error */ + } + EnterCritical(); /* Disable global interrupts */ + AS2_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = Chr; /* Store char to buffer */ + if (OutIndexW >= AS2_OUT_BUF_SIZE) { /* Is the pointer out of the transmit buffer */ + OutIndexW = 0x00U; /* Set index to first item in the transmit buffer */ + } + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv) +{ + register word count; /* Number of received chars */ + register byte result = ERR_OK; /* Last error */ + + for (count = 0x00U; count < Size; count++) { + switch (AS2_RecvChar(Ptr++)) { /* Receive data and test the return value*/ + case ERR_RXEMPTY: /* No data in the buffer */ + if (result == ERR_OK) { /* If no receiver error reported */ + result = ERR_RXEMPTY; /* Return info that requested number of data is not available */ + } + *Rcv = count; /* Return number of received chars */ + return result; + case ERR_COMMON: /* Receiver error reported */ + result = ERR_COMMON; /* Return info that an error was detected */ + break; + default: + break; + } + } + *Rcv = count; /* Return number of received chars */ + return result; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd) +{ + word count = 0x00U; /* Number of sent chars */ + AS2_TComData *TmpPtr = Ptr; /* Temporary output buffer pointer */ + + while ((count < Size) && (AS2_OutLen < AS2_OUT_BUF_SIZE)) { /* While there is some char desired to send left and output buffer is not full do */ + EnterCritical(); /* Enter the critical section */ + AS2_OutLen++; /* Increase number of bytes in the transmit buffer */ + OutBuffer[OutIndexW++] = *TmpPtr++; /* Store char to buffer */ + if (OutIndexW >= AS2_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexW = 0x00U; /* Set index to the first item in the transmit buffer */ + } + count++; /* Increase the count of sent data */ + if ((SerFlag & RUNINT_FROM_TX) == 0U) { + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } + ExitCritical(); /* Exit the critical section */ + } + *Snd = count; /* Return number of sent chars */ + if (count != Size) { /* Is the number of sent chars less then desired number of chars */ + return ERR_TXFULL; /* If yes then error */ + } + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearRxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS2_InpLen = 0x00U; /* Set number of chars in the transmit buffer to 0 */ + InpIndexW = 0x00U; /* Set index on the first item in the transmit buffer */ + InpIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearTxBuf(void) +{ + EnterCritical(); /* Disable global interrupts */ + AS2_OutLen = 0x00U; /* Set number of chars in the receive buffer to 0 */ + OutIndexW = 0x00U; /* Set index on the first item in the receive buffer */ + OutIndexR = 0x00U; + ExitCritical(); /* Enable global interrupts */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : AS2_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInRxBuf(void) +{ + return AS2_InpLen; /* Return number of chars in receive buffer */ +} + +/* +** =================================================================== +** Method : AS2_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInTxBuf(void) +{ + return AS2_OutLen; /* Return number of chars in the transmitter buffer */ +} + +/* +** =================================================================== +** Method : AS2_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS2_Init(void) +{ + SerFlag = 0x00U; /* Reset flags */ + AS2_InpLen = 0x00U; /* No char in the receive buffer */ + InpIndexR = 0x00U; /* Set index on the first item in the receive buffer */ + InpIndexW = 0x00U; + AS2_OutLen = 0x00U; /* No char in the transmit buffer */ + OutIndexR = 0x00U; /* Set index on the first item in the transmit buffer */ + OutIndexW = 0x00U; + ASerialLdd2_DeviceDataPtr = ASerialLdd2_Init(NULL); /* Calling init method of the inherited component */ + HWEnDi(); /* Enable/disable device according to status flags */ +} + +#define ON_ERROR 0x01U +#define ON_FULL_RX 0x02U +#define ON_RX_CHAR 0x04U +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockReceived(LDD_TUserData *UserDataPtr) +{ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (AS2_InpLen < AS2_INP_BUF_SIZE) { /* Is number of bytes in the receive buffer lower than size of buffer? */ + AS2_InpLen++; /* Increase number of chars in the receive buffer */ + InpBuffer[InpIndexW++] = (AS2_TComData)BufferRead; /* Save received char to the receive buffer */ + if (InpIndexW >= AS2_INP_BUF_SIZE) { /* Is the index out of the receive buffer? */ + InpIndexW = 0x00U; /* Set index on the first item into the receive buffer */ + } + } else { + SerFlag |= FULL_RX; /* Set flag "full RX buffer" */ + } + (void)ASerialLdd2_ReceiveBlock(ASerialLdd2_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */ +} + +#define ON_FREE_TX 0x01U +#define ON_TX_CHAR 0x02U +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockSent(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + OutIndexR++; + if (OutIndexR >= AS2_OUT_BUF_SIZE) { /* Is the index out of the transmit buffer? */ + OutIndexR = 0x00U; /* Set index on the first item into the transmit buffer */ + } + AS2_OutLen--; /* Decrease number of chars in the transmit buffer */ + if (AS2_OutLen != 0U) { /* Is number of bytes in the transmit buffer greater then 0? */ + SerFlag |= RUNINT_FROM_TX; /* Set flag "running int from TX"? */ + (void)ASerialLdd2_SendBlock(ASerialLdd2_DeviceDataPtr, (LDD_TData *)&OutBuffer[OutIndexR], 1U); /* Send one data byte */ + } else { + SerFlag &= (byte)~(RUNINT_FROM_TX); /* Clear "running int from TX" and "full TX buff" flags */ + } +} + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnError(LDD_TUserData *UserDataPtr) +{ + LDD_SERIAL_TError SerialErrorMask; /* Serial error mask variable */ + + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + (void)ASerialLdd2_GetError(ASerialLdd2_DeviceDataPtr, &SerialErrorMask); /* Get error state */ + if (SerialErrorMask != 0U) { + SerFlag |= (((SerialErrorMask & LDD_SERIAL_PARITY_ERROR) != 0U ) ? PARITY_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_NOISE_ERROR) != 0U ) ? NOISE_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_RX_OVERRUN) != 0U ) ? OVERRUN_ERR : 0U); + SerFlag |= (((SerialErrorMask & LDD_SERIAL_FRAMING_ERROR) != 0U ) ? FRAMING_ERR : 0U); + } +} + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBreak(LDD_TUserData *UserDataPtr) +{ + (void)UserDataPtr; /* Parameter is not used, suppress unused argument warning */ + SerFlag |= FRAMING_ERR; /* Set framing error flag */ +} + + +/* END AS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.h new file mode 100644 index 0000000..6fb175f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/AS2.h @@ -0,0 +1,417 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : AS2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : AsynchroSerial +** Version : Component 02.611, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +** Settings : +** Component name : AS2 +** Channel : UART2 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART2_RX_TX +** Interrupt RxD priority : 2 +** Interrupt TxD : INT_UART2_RX_TX +** Interrupt TxD priority : 2 +** Interrupt Error : INT_UART2_ERR +** Interrupt Error priority : 2 +** Input buffer size : 64 +** Output buffer size : 128 +** Handshake : +** CTS : Disabled +** RTS : Disabled +** Settings : +** Parity : none +** Width : 8 bits +** Stop bit : 1 +** Receiver : Enabled +** RxD : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** RxD pin signal : UART_SWD_RX +** Transmitter : Enabled +** TxD : PTD3/SPI0_SIN/UART2_TX +** TxD pin signal : UART_SWD_TX +** Baud rate : 38400 baud +** Break signal : Disabled +** Wakeup condition : Idle line wakeup +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Stop in wait mode : no +** Idle line mode : starts after start bit +** Break generation length : Short +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** Serial_LDD : Serial_LDD +** Contents : +** RecvChar - byte AS2_RecvChar(AS2_TComData *Chr); +** SendChar - byte AS2_SendChar(AS2_TComData Chr); +** RecvBlock - byte AS2_RecvBlock(AS2_TComData *Ptr, word Size, word *Rcv); +** SendBlock - byte AS2_SendBlock(AS2_TComData *Ptr, word Size, word *Snd); +** ClearRxBuf - byte AS2_ClearRxBuf(void); +** ClearTxBuf - byte AS2_ClearTxBuf(void); +** GetCharsInRxBuf - word AS2_GetCharsInRxBuf(void); +** GetCharsInTxBuf - word AS2_GetCharsInTxBuf(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file AS2.h +** @version 01.01 +** @brief +** This component "AsynchroSerial" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial channel. +*/ +/*! +** @addtogroup AS2_module AS2 module documentation +** @{ +*/ + +#ifndef __AS2 +#define __AS2 + +/* MODULE AS2. */ + +/* Include inherited components */ +#include "ASerialLdd2.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifndef __BWUserType_AS2_TError +#define __BWUserType_AS2_TError + typedef union { + byte err; + struct { + bool OverRun : 1; /* Overrun error flag */ + bool Framing : 1; /* Framing error flag */ + bool Parity : 1; /* Parity error flag */ + bool RxBufOvf : 1; /* Rx buffer full error flag */ + bool Noise : 1; /* Noise error flag */ + bool Break : 1; /* Break detect */ + bool LINSync : 1; /* LIN synchronization error */ + bool BitError : 1; /* Bit error flag - mismatch to the expected value happened. */ + } errName; +} AS2_TError; /* Error flags. For languages which don't support bit access is byte access only to error flags possible. */ +#endif + +#ifndef __BWUserType_AS2_TComData +#define __BWUserType_AS2_TComData + typedef byte AS2_TComData; /* User type for communication. Size of this type depends on the communication data witdh */ +#endif + +#define AS2_INP_BUF_SIZE 0x40U /* Length of the RX buffer */ + +#define AS2_OUT_BUF_SIZE 0x80U /* Length of the TX buffer */ + +/* +** =================================================================== +** Method : AS2_RecvChar (component AsynchroSerial) +** Description : +** If any data is received, this method returns one character, +** otherwise it returns an error code (it does not wait for +** data). This method is enabled only if the receiver property +** is enabled. +** [Note:] Because the preferred method to handle error and +** break exception in the interrupt mode is to use events +** and the return value ERR_RXEMPTY has +** higher priority than other error codes. As a consequence the +** information about an exception in interrupt mode is returned +** only if there is a valid character ready to be read. +** Parameters : +** NAME - DESCRIPTION +** * Chr - Pointer to a received character +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - No data in receiver +** ERR_BREAK - Break character is detected +** (only when the property +** is disabled and the property +** is enabled) +** ERR_COMMON - common error occurred (the +** method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvChar(AS2_TComData *Chr); + +/* +** =================================================================== +** Method : AS2_SendChar (component AsynchroSerial) +** Description : +** Sends one character to the channel. If the component is +** temporarily disabled (Disable method) SendChar method only +** stores data into an output buffer. In case of a zero output +** buffer size, only one character can be stored. Enabling the +** component (Enable method) starts the transmission of the +** stored data. This method is available only if the +** transmitter property is enabled. +** Parameters : +** NAME - DESCRIPTION +** Chr - Character to send +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - Transmitter is full +** =================================================================== +*/ +byte AS2_SendChar(AS2_TComData Chr); + +/* +** =================================================================== +** Method : AS2_RecvBlock (component AsynchroSerial) +** Description : +** If any data is received, this method returns the block of +** the data and its length (and incidental error), otherwise it +** returns an error code (it does not wait for data). +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** If less than requested number of characters is received only +** the available data is copied from the receive buffer to the +** user specified destination. The value ERR_EXEMPTY is +** returned and the value of variable pointed by the Rcv +** parameter is set to the number of received characters. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of received data +** Size - Size of the block +** * Rcv - Pointer to real number of the received data +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_RXEMPTY - The receive buffer didn't +** contain the requested number of data. Only +** available data has been returned. +** ERR_COMMON - common error occurred (the +** GetError method can be used for error +** specification) +** =================================================================== +*/ +byte AS2_RecvBlock(AS2_TComData *Ptr,word Size,word *Rcv); + +/* +** =================================================================== +** Method : AS2_SendBlock (component AsynchroSerial) +** Description : +** Sends a block of characters to the channel. +** This method is available only if non-zero length of the +** output buffer is defined and the transmitter property is +** enabled. +** Parameters : +** NAME - DESCRIPTION +** * Ptr - Pointer to the block of data to send +** Size - Size of the block +** * Snd - Pointer to number of data that are sent +** (moved to buffer) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_TXFULL - It was not possible to send +** requested number of bytes +** =================================================================== +*/ +byte AS2_SendBlock(AS2_TComData *Ptr,word Size,word *Snd); + +/* +** =================================================================== +** Method : AS2_ClearRxBuf (component AsynchroSerial) +** Description : +** Clears the receive buffer. +** This method is available only if non-zero length of the +** input buffer is defined and the receiver property is enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearRxBuf(void); + +/* +** =================================================================== +** Method : AS2_ClearTxBuf (component AsynchroSerial) +** Description : +** Clears the transmit buffer. +** This method is available only if non-zero length of the +** output buffer is defined and the receiver property is +** enabled. +** Parameters : None +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +byte AS2_ClearTxBuf(void); + +/* +** =================================================================== +** Method : AS2_GetCharsInRxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the input buffer. This +** method is available only if the receiver property is enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the input +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInRxBuf(void); + +/* +** =================================================================== +** Method : AS2_GetCharsInTxBuf (component AsynchroSerial) +** Description : +** Returns the number of characters in the output buffer. This +** method is available only if the transmitter property is +** enabled. +** Parameters : None +** Returns : +** --- - The number of characters in the output +** buffer. +** =================================================================== +*/ +word AS2_GetCharsInTxBuf(void); + +/* +** =================================================================== +** Method : AS2_Init (component AsynchroSerial) +** +** Description : +** Initializes the associated peripheral(s) and the bean internal +** variables. The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void AS2_Init(void); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockReceived (component AsynchroSerial) +** +** Description : +** This event is called when the requested number of data is +** moved to the input buffer. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockReceived(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBlockSent (component AsynchroSerial) +** +** Description : +** This event is called after the last character from the output +** buffer is moved to the transmitter. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBlockSent(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnError (component AsynchroSerial) +** +** Description : +** This event is called when a channel error (not the error +** returned by a given method) occurs. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnError(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : AS2_ASerialLdd2_OnBreak (component AsynchroSerial) +** +** Description : +** This event is called when a break occurs on the input channel. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void ASerialLdd2_OnBreak(LDD_TUserData *UserDataPtr); + + +/* END AS2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ifndef __AS2 */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.c new file mode 100644 index 0000000..4dd6429 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.c @@ -0,0 +1,525 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd1 +** Device : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : 1 +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : 1 +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : 1 +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** RxD pin signal : +** Transmitter : Enabled +** TxD : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** TxD pin signal : +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd1.c +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd1_module ASerialLdd1 module documentation +** @{ +*/ + +/* MODULE ASerialLdd1. */ +/*lint -save -e926 -e927 -e928 -e929 -e572 Disable MISRA rule (11.4,12.8) checking. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "ASerialLdd1.h" +#include "AS1.h" +#include "UART_PDD.h" +#include "SIM_PDD.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! The mask of available events used to enable/disable events during runtime. */ +#define AVAILABLE_EVENTS_MASK (LDD_SERIAL_ON_BLOCK_RECEIVED | LDD_SERIAL_ON_BLOCK_SENT | LDD_SERIAL_ON_BREAK | LDD_SERIAL_ON_ERROR) + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static ASerialLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd1_TDeviceDataPtr INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd1_TDeviceDataPtr INT_UART0_ERR__BAREBOARD_RTOS_ISRPARAM; + +/* +** =================================================================== +** Method : ASerialLdd1_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + + /* Clear the receive counters and pointer */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ + DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ + /* Clear the transmit counters and pointer */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Allocate interrupt vectors */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART0_ERR__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC4: UART0=1 */ + SIM_SCGC4 |= SIM_SCGC4_UART0_MASK; + /* PORTD_PCR6: ISF=0,MUX=3 */ + PORTD_PCR6 = (uint32_t)((PORTD_PCR6 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* PORTD_PCR7: ISF=0,MUX=3 */ + PORTD_PCR7 = (uint32_t)((PORTD_PCR7 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* NVICIP16: PRI16=0x10 */ + NVICIP16 = NVIC_IP_PRI16(0x10); + /* NVICISER0: SETENA|=0x00010000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x00010000); + /* NVICIP17: PRI17=0x10 */ + NVICIP17 = NVIC_IP_PRI17(0x10); + /* NVICISER0: SETENA|=0x00020000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x00020000); + UART_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_DISABLE); /* Disable transmitter. */ + UART_PDD_EnableReceiver(UART0_BASE_PTR, PDD_DISABLE); /* Disable receiver. */ + DeviceDataPrv->SerFlag = 0x00U; /* Reset flags */ + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* UART0_C1: LOOPS=0,UARTSWAI=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */ + UART0_C1 = 0x00U; /* Set the C1 register */ + /* UART0_C3: R8=0,T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */ + UART0_C3 = 0x00U; /* Set the C3 register */ + /* UART0_C4: MAEN1=0,MAEN2=0,M10=0,BRFA=0 */ + UART0_C4 = UART_C4_BRFA(0x00); /* Set the C4 register */ + /* UART0_S2: LBKDIF=0,RXEDGIF=0,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */ + UART0_S2 = 0x00U; /* Set the S2 register */ + /* UART0_MODEM: ??=0,??=0,??=0,??=0,RXRTSE=0,TXRTSPOL=0,TXRTSE=0,TXCTSE=0 */ + UART0_MODEM = 0x00U; /* Set the MODEM register */ + UART_PDD_SetBaudRateFineAdjust(UART0_BASE_PTR, 12u); /* Set baud rate fine adjust */ + UART_PDD_SetBaudRate(UART0_BASE_PTR, 81U); /* Set the baud rate register. */ + UART_PDD_EnableFifo(UART0_BASE_PTR, (UART_PDD_TX_FIFO_ENABLE | UART_PDD_RX_FIFO_ENABLE)); /* Enable RX and TX FIFO */ + UART_PDD_FlushFifo(UART0_BASE_PTR, (UART_PDD_TX_FIFO_FLUSH | UART_PDD_RX_FIFO_FLUSH)); /* Flush RX and TX FIFO */ + UART_PDD_EnableTransmitter(UART0_BASE_PTR, PDD_ENABLE); /* Enable transmitter */ + UART_PDD_EnableReceiver(UART0_BASE_PTR, PDD_ENABLE); /* Enable receiver */ + UART_PDD_EnableInterrupt(UART0_BASE_PTR, ( UART_PDD_INTERRUPT_RECEIVER | UART_PDD_INTERRUPT_PARITY_ERROR | UART_PDD_INTERRUPT_FRAMING_ERROR | UART_PDD_INTERRUPT_NOISE_ERROR | UART_PDD_INTERRUPT_OVERRUN_ERROR )); /* Enable interrupts */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ASerialLdd1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} + +/* +** =================================================================== +** Method : ASerialLdd1_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the previous receive operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */ + DeviceDataPrv->InpDataNumReq = Size; /* Store a number of characters to be received. */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : ASerialLdd1_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->OutDataNumReq != 0x00U) { /* Is the previous transmit operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->OutDataPtr = (uint8_t*)BufferPtr; /* Set a pointer to the output data. */ + DeviceDataPrv->OutDataNumReq = Size; /* Set the counter of characters to be sent. */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters. */ + DeviceDataPrv->SerFlag |= ENABLED_TX_INT; /* Set the flag ENABLED_TX_INT */ + UART_PDD_EnableInterrupt(UART0_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Enable TX interrupt */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : InterruptRx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptRx(ASerialLdd1_TDeviceDataPtr DeviceDataPrv) +{ + register uint16_t Data; /* Temporary variable for data */ + + Data = (uint16_t)UART_PDD_GetChar8(UART0_BASE_PTR); /* Read an 8-bit character from the receiver */ + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */ + *(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put an 8-bit character to the receive buffer */ + DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */ + if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */ + ASerialLdd1_OnBlockReceived(DeviceDataPrv->UserDataPtr); + } + } +} + +/* +** =================================================================== +** Method : InterruptTx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptTx(ASerialLdd1_TDeviceDataPtr DeviceDataPrv) +{ + + if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */ + UART_PDD_PutChar8(UART0_BASE_PTR, *(DeviceDataPrv->OutDataPtr++)); /* Put a 8-bit character to the transmit register */ + DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */ + if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) { + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + ASerialLdd1_OnBlockSent(DeviceDataPrv->UserDataPtr); + } + } else { + UART_PDD_DisableInterrupt(UART0_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Disable TX interrupt */ + DeviceDataPrv->SerFlag &= (uint16_t)(~(uint16_t)ENABLED_TX_INT); /* Clear the flag ENABLED_TX_INT */ + } +} + +/* +** =================================================================== +** Method : ASerialLdd1_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(ASerialLdd1_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = INT_UART0_RX_TX__BAREBOARD_RTOS_ISRPARAM; + register uint32_t StatReg = UART_PDD_ReadInterruptStatusReg(UART0_BASE_PTR); /* Read status register */ + register uint16_t OnErrorFlags = 0U; /* Temporary variable for flags */ + register uint8_t OnBreakFlag = 0U; /* Temporary variable flag for OnBreak event */ + register uint16_t Data; /* Temporary variable for data */ + + if (StatReg & (UART_S1_NF_MASK | UART_S1_OR_MASK | UART_S1_FE_MASK | UART_S1_PF_MASK)) { /* Is any error flag set? */ + Data = (uint16_t)UART_PDD_GetChar8(UART0_BASE_PTR); /* Read an 8-bit character from receiver */ + if ((StatReg & UART_S1_FE_MASK) != 0U) { /* Is the framing error detected? */ + if (((StatReg & UART_S1_RDRF_MASK) != 0U) && (Data == 0U)) { /* Is the zero character in the receiver? */ + OnBreakFlag++; + DeviceDataPrv->SerFlag |= BREAK_DETECTED; /* If yes then set the flag */ + } else { + OnErrorFlags |= LDD_SERIAL_FRAMING_ERROR; /* If yes then set the flag */ + } + } + if ((StatReg & UART_S1_OR_MASK) != 0U) { /* Is the overrun error flag set? */ + OnErrorFlags |= LDD_SERIAL_RX_OVERRUN; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_PF_MASK) != 0U) { /* Is the parity error flag set? */ + OnErrorFlags |= LDD_SERIAL_PARITY_ERROR; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_NF_MASK) != 0U) { /* Is the noise error flag set? */ + OnErrorFlags |= LDD_SERIAL_NOISE_ERROR; /* If yes then set the flag */ + } + DeviceDataPrv->ErrFlag |= OnErrorFlags; /* Copy flags status to ErrFlag status variable */ + StatReg &= (uint32_t)(~(uint32_t)UART_S1_RDRF_MASK); /* Clear the receive data flag to discard the errorneous data */ + if (OnBreakFlag != 0U) { + ASerialLdd1_OnBreak(DeviceDataPrv->UserDataPtr); /* If yes then invoke user event */ + } else { + ASerialLdd1_OnError(DeviceDataPrv->UserDataPtr); /* Invoke user event */ + } + } + if (StatReg & UART_S1_RDRF_MASK) { /* Is the receiver's interrupt flag set? */ + InterruptRx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + if (DeviceDataPrv->SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */ + if (StatReg & UART_S1_TDRE_MASK) { /* Is the transmitter empty? */ + InterruptTx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + } +} + +/* +** =================================================================== +** Method : ASerialLdd1_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr) +{ + ASerialLdd1_TDeviceDataPtr DeviceDataPrv = (ASerialLdd1_TDeviceDataPtr)DeviceDataPtr; + + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + *ErrorPtr = DeviceDataPrv->ErrFlag; + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/*lint -restore Enable MISRA rule (11.4,12.8) checking. */ +/* END ASerialLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.h new file mode 100644 index 0000000..e5aaeda --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd1.h @@ -0,0 +1,339 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd1 +** Device : UART0 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART0_RX_TX +** Interrupt RxD priority : 1 +** Interrupt TxD : INT_UART0_RX_TX +** Interrupt TxD priority : 1 +** Interrupt Error : INT_UART0_ERR +** Interrupt Error priority : 1 +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : ADC0_SE7b/PTD6/LLWU_P15/SPI0_PCS3/UART0_RX/FTM0_CH6/FTM0_FLT0 +** RxD pin signal : +** Transmitter : Enabled +** TxD : PTD7/CMT_IRO/UART0_TX/FTM0_CH7/FTM0_FLT1 +** TxD pin signal : +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd1.h +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd1_module ASerialLdd1 module documentation +** @{ +*/ + +#ifndef __ASerialLdd1_H +#define __ASerialLdd1_H + +/* MODULE ASerialLdd1. */ + + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define ASerialLdd1_PRPH_BASE_ADDRESS 0x4006A000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define ASerialLdd1_Init_METHOD_ENABLED /*!< Init method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_SendBlock_METHOD_ENABLED /*!< SendBlock method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_ReceiveBlock_METHOD_ENABLED /*!< ReceiveBlock method of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_GetError_METHOD_ENABLED /*!< GetError method of the component ASerialLdd1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define ASerialLdd1_OnBlockReceived_EVENT_ENABLED /*!< OnBlockReceived event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnBlockSent_EVENT_ENABLED /*!< OnBlockSent event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnBreak_EVENT_ENABLED /*!< OnBreak event of the component ASerialLdd1 is enabled (generated) */ +#define ASerialLdd1_OnError_EVENT_ENABLED /*!< OnError event of the component ASerialLdd1 is enabled (generated) */ + +#define ENABLED_TX_INT 0x01U /*!< TX interrupt enabled */ +#define BREAK_DETECTED 0x02U /*!< Break detected */ +#define TX_COMPLETED 0x04U /*!< Transmission completed */ +#define ENABLE_TX_COMPLETE 0x10U /*!< Enable/Disable of TX complete detection. Used in the polling mode only */ + +/*! Device data structure type */ +typedef struct { + uint16_t SerFlag; /*!< Flags for serial communication */ + LDD_SERIAL_TError ErrFlag; /*!< Error flags mirror of SerFlag */ + uint16_t InpRecvDataNum; /*!< The counter of received characters */ + uint8_t *InpDataPtr; /*!< The buffer pointer for received characters */ + uint16_t InpDataNumReq; /*!< The counter of characters to receive by ReceiveBlock() */ + uint16_t OutSentDataNum; /*!< The counter of sent characters */ + uint8_t *OutDataPtr; /*!< The buffer pointer for data to be transmitted */ + uint16_t OutDataNumReq; /*!< The counter of characters to be send by SendBlock() */ + LDD_TUserData *UserDataPtr; /*!< Pointer to user data */ +} ASerialLdd1_TDeviceData; + +typedef ASerialLdd1_TDeviceData *ASerialLdd1_TDeviceDataPtr ; /*!< Pointer to the device data structure. */ + +/* +** =================================================================== +** Method : ASerialLdd1_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : ASerialLdd1_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd1_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd1_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(ASerialLdd1_Interrupt); + +/* +** =================================================================== +** Method : ASerialLdd1_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd1_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr); + +/* END ASerialLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __ASerialLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.c new file mode 100644 index 0000000..a91dc5e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.c @@ -0,0 +1,525 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd2 +** Device : UART2 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART2_RX_TX +** Interrupt RxD priority : 2 +** Interrupt TxD : INT_UART2_RX_TX +** Interrupt TxD priority : 2 +** Interrupt Error : INT_UART2_ERR +** Interrupt Error priority : 2 +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** RxD pin signal : UART_SWD_RX +** Transmitter : Enabled +** TxD : PTD3/SPI0_SIN/UART2_TX +** TxD pin signal : UART_SWD_TX +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd2.c +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd2_module ASerialLdd2 module documentation +** @{ +*/ + +/* MODULE ASerialLdd2. */ +/*lint -save -e926 -e927 -e928 -e929 -e572 Disable MISRA rule (11.4,12.8) checking. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "ASerialLdd2.h" +#include "AS2.h" +#include "UART_PDD.h" +#include "SIM_PDD.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*! The mask of available events used to enable/disable events during runtime. */ +#define AVAILABLE_EVENTS_MASK (LDD_SERIAL_ON_BLOCK_RECEIVED | LDD_SERIAL_ON_BLOCK_SENT | LDD_SERIAL_ON_BREAK | LDD_SERIAL_ON_ERROR) + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static ASerialLdd2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd2_TDeviceDataPtr INT_UART2_RX_TX__BAREBOARD_RTOS_ISRPARAM; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static ASerialLdd2_TDeviceDataPtr INT_UART2_ERR__BAREBOARD_RTOS_ISRPARAM; + +/* +** =================================================================== +** Method : ASerialLdd2_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + + /* Clear the receive counters and pointer */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Clear the counter of received characters */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* Clear the counter of characters to receive by ReceiveBlock() */ + DeviceDataPrv->InpDataPtr = NULL; /* Clear the buffer pointer for received characters */ + /* Clear the transmit counters and pointer */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters */ + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + DeviceDataPrv->OutDataPtr = NULL; /* Clear the buffer pointer for data to be transmitted */ + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Allocate interrupt vectors */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART2_RX_TX__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_UART2_ERR__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC4: UART2=1 */ + SIM_SCGC4 |= SIM_SCGC4_UART2_MASK; + /* PORTD_PCR2: ISF=0,MUX=3 */ + PORTD_PCR2 = (uint32_t)((PORTD_PCR2 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* PORTD_PCR3: ISF=0,MUX=3 */ + PORTD_PCR3 = (uint32_t)((PORTD_PCR3 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x04) + )) | (uint32_t)( + PORT_PCR_MUX(0x03) + )); + /* NVICIP20: PRI20=0x20 */ + NVICIP20 = NVIC_IP_PRI20(0x20); + /* NVICISER0: SETENA|=0x00100000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x00100000); + /* NVICIP21: PRI21=0x20 */ + NVICIP21 = NVIC_IP_PRI21(0x20); + /* NVICISER0: SETENA|=0x00200000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x00200000); + UART_PDD_EnableTransmitter(UART2_BASE_PTR, PDD_DISABLE); /* Disable transmitter. */ + UART_PDD_EnableReceiver(UART2_BASE_PTR, PDD_DISABLE); /* Disable receiver. */ + DeviceDataPrv->SerFlag = 0x00U; /* Reset flags */ + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* UART2_C1: LOOPS=0,UARTSWAI=0,RSRC=0,M=0,WAKE=0,ILT=0,PE=0,PT=0 */ + UART2_C1 = 0x00U; /* Set the C1 register */ + /* UART2_C3: R8=0,T8=0,TXDIR=0,TXINV=0,ORIE=0,NEIE=0,FEIE=0,PEIE=0 */ + UART2_C3 = 0x00U; /* Set the C3 register */ + /* UART2_C4: MAEN1=0,MAEN2=0,M10=0,BRFA=0 */ + UART2_C4 = UART_C4_BRFA(0x00); /* Set the C4 register */ + /* UART2_S2: LBKDIF=0,RXEDGIF=0,MSBF=0,RXINV=0,RWUID=0,BRK13=0,LBKDE=0,RAF=0 */ + UART2_S2 = 0x00U; /* Set the S2 register */ + /* UART2_MODEM: ??=0,??=0,??=0,??=0,RXRTSE=0,TXRTSPOL=0,TXRTSE=0,TXCTSE=0 */ + UART2_MODEM = 0x00U; /* Set the MODEM register */ + UART_PDD_SetBaudRateFineAdjust(UART2_BASE_PTR, 22u); /* Set baud rate fine adjust */ + UART_PDD_SetBaudRate(UART2_BASE_PTR, 40U); /* Set the baud rate register. */ + UART_PDD_EnableFifo(UART2_BASE_PTR, (UART_PDD_TX_FIFO_ENABLE | UART_PDD_RX_FIFO_ENABLE)); /* Enable RX and TX FIFO */ + UART_PDD_FlushFifo(UART2_BASE_PTR, (UART_PDD_TX_FIFO_FLUSH | UART_PDD_RX_FIFO_FLUSH)); /* Flush RX and TX FIFO */ + UART_PDD_EnableTransmitter(UART2_BASE_PTR, PDD_ENABLE); /* Enable transmitter */ + UART_PDD_EnableReceiver(UART2_BASE_PTR, PDD_ENABLE); /* Enable receiver */ + UART_PDD_EnableInterrupt(UART2_BASE_PTR, ( UART_PDD_INTERRUPT_RECEIVER | UART_PDD_INTERRUPT_PARITY_ERROR | UART_PDD_INTERRUPT_FRAMING_ERROR | UART_PDD_INTERRUPT_NOISE_ERROR | UART_PDD_INTERRUPT_OVERRUN_ERROR )); /* Enable interrupts */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_ASerialLdd2_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} + +/* +** =================================================================== +** Method : ASerialLdd2_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the previous receive operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->InpDataPtr = (uint8_t*)BufferPtr; /* Store a pointer to the input data. */ + DeviceDataPrv->InpDataNumReq = Size; /* Store a number of characters to be received. */ + DeviceDataPrv->InpRecvDataNum = 0x00U; /* Set number of received characters to zero. */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : ASerialLdd2_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + if (Size == 0U) { /* Is the parameter Size within an expected range? */ + return ERR_PARAM_SIZE; /* If no then error */ + } + if (DeviceDataPrv->OutDataNumReq != 0x00U) { /* Is the previous transmit operation pending? */ + return ERR_BUSY; /* If yes then error */ + } + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + DeviceDataPrv->OutDataPtr = (uint8_t*)BufferPtr; /* Set a pointer to the output data. */ + DeviceDataPrv->OutDataNumReq = Size; /* Set the counter of characters to be sent. */ + DeviceDataPrv->OutSentDataNum = 0x00U; /* Clear the counter of sent characters. */ + DeviceDataPrv->SerFlag |= ENABLED_TX_INT; /* Set the flag ENABLED_TX_INT */ + UART_PDD_EnableInterrupt(UART2_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Enable TX interrupt */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : InterruptRx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptRx(ASerialLdd2_TDeviceDataPtr DeviceDataPrv) +{ + register uint16_t Data; /* Temporary variable for data */ + + Data = (uint16_t)UART_PDD_GetChar8(UART2_BASE_PTR); /* Read an 8-bit character from the receiver */ + if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */ + *(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put an 8-bit character to the receive buffer */ + DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */ + if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */ + DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */ + ASerialLdd2_OnBlockReceived(DeviceDataPrv->UserDataPtr); + } + } +} + +/* +** =================================================================== +** Method : InterruptTx (component Serial_LDD) +** +** Description : +** The method services the receive interrupt of the selected +** peripheral(s) and eventually invokes the bean's event(s). +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void InterruptTx(ASerialLdd2_TDeviceDataPtr DeviceDataPrv) +{ + + if (DeviceDataPrv->OutSentDataNum < DeviceDataPrv->OutDataNumReq) { /* Is number of sent characters less than the number of requested incoming characters? */ + UART_PDD_PutChar8(UART2_BASE_PTR, *(DeviceDataPrv->OutDataPtr++)); /* Put a 8-bit character to the transmit register */ + DeviceDataPrv->OutSentDataNum++; /* Increment the counter of sent characters. */ + if (DeviceDataPrv->OutSentDataNum == DeviceDataPrv->OutDataNumReq) { + DeviceDataPrv->OutDataNumReq = 0x00U; /* Clear the counter of characters to be send by SendBlock() */ + ASerialLdd2_OnBlockSent(DeviceDataPrv->UserDataPtr); + } + } else { + UART_PDD_DisableInterrupt(UART2_BASE_PTR, UART_PDD_INTERRUPT_TRANSMITTER); /* Disable TX interrupt */ + DeviceDataPrv->SerFlag &= (uint16_t)(~(uint16_t)ENABLED_TX_INT); /* Clear the flag ENABLED_TX_INT */ + } +} + +/* +** =================================================================== +** Method : ASerialLdd2_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(ASerialLdd2_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = INT_UART2_RX_TX__BAREBOARD_RTOS_ISRPARAM; + register uint32_t StatReg = UART_PDD_ReadInterruptStatusReg(UART2_BASE_PTR); /* Read status register */ + register uint16_t OnErrorFlags = 0U; /* Temporary variable for flags */ + register uint8_t OnBreakFlag = 0U; /* Temporary variable flag for OnBreak event */ + register uint16_t Data; /* Temporary variable for data */ + + if (StatReg & (UART_S1_NF_MASK | UART_S1_OR_MASK | UART_S1_FE_MASK | UART_S1_PF_MASK)) { /* Is any error flag set? */ + Data = (uint16_t)UART_PDD_GetChar8(UART2_BASE_PTR); /* Read an 8-bit character from receiver */ + if ((StatReg & UART_S1_FE_MASK) != 0U) { /* Is the framing error detected? */ + if (((StatReg & UART_S1_RDRF_MASK) != 0U) && (Data == 0U)) { /* Is the zero character in the receiver? */ + OnBreakFlag++; + DeviceDataPrv->SerFlag |= BREAK_DETECTED; /* If yes then set the flag */ + } else { + OnErrorFlags |= LDD_SERIAL_FRAMING_ERROR; /* If yes then set the flag */ + } + } + if ((StatReg & UART_S1_OR_MASK) != 0U) { /* Is the overrun error flag set? */ + OnErrorFlags |= LDD_SERIAL_RX_OVERRUN; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_PF_MASK) != 0U) { /* Is the parity error flag set? */ + OnErrorFlags |= LDD_SERIAL_PARITY_ERROR; /* If yes then set the flag */ + } + if ((StatReg & UART_S1_NF_MASK) != 0U) { /* Is the noise error flag set? */ + OnErrorFlags |= LDD_SERIAL_NOISE_ERROR; /* If yes then set the flag */ + } + DeviceDataPrv->ErrFlag |= OnErrorFlags; /* Copy flags status to ErrFlag status variable */ + StatReg &= (uint32_t)(~(uint32_t)UART_S1_RDRF_MASK); /* Clear the receive data flag to discard the errorneous data */ + if (OnBreakFlag != 0U) { + ASerialLdd2_OnBreak(DeviceDataPrv->UserDataPtr); /* If yes then invoke user event */ + } else { + ASerialLdd2_OnError(DeviceDataPrv->UserDataPtr); /* Invoke user event */ + } + } + if (StatReg & UART_S1_RDRF_MASK) { /* Is the receiver's interrupt flag set? */ + InterruptRx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + if (DeviceDataPrv->SerFlag & ENABLED_TX_INT) { /* Is the transmitter interrupt enabled? */ + if (StatReg & UART_S1_TDRE_MASK) { /* Is the transmitter empty? */ + InterruptTx(DeviceDataPrv); /* If yes, then invoke the internal service routine. This routine is inlined. */ + } + } +} + +/* +** =================================================================== +** Method : ASerialLdd2_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr) +{ + ASerialLdd2_TDeviceDataPtr DeviceDataPrv = (ASerialLdd2_TDeviceDataPtr)DeviceDataPtr; + + /* {FreeRTOS RTOS Adapter} Critical section begin (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + EnterCritical(); + *ErrorPtr = DeviceDataPrv->ErrFlag; + DeviceDataPrv->ErrFlag = 0x00U; /* Reset error flags */ + /* {FreeRTOS RTOS Adapter} Critical section ends (RTOS function call is defined by FreeRTOS RTOS Adapter property) */ + ExitCritical(); + return ERR_OK; /* OK */ +} + +/*lint -restore Enable MISRA rule (11.4,12.8) checking. */ +/* END ASerialLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.h new file mode 100644 index 0000000..fcac0c2 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ASerialLdd2.h @@ -0,0 +1,339 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ASerialLdd2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Serial_LDD +** Version : Component 01.188, Driver 01.12, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +** Settings : +** Component name : ASerialLdd2 +** Device : UART2 +** Interrupt service/event : Enabled +** Interrupt RxD : INT_UART2_RX_TX +** Interrupt RxD priority : 2 +** Interrupt TxD : INT_UART2_RX_TX +** Interrupt TxD priority : 2 +** Interrupt Error : INT_UART2_ERR +** Interrupt Error priority : 2 +** Settings : +** Data width : 8 bits +** Parity : None +** Stop bits : 1 +** Loop mode : Normal +** Baud rate : 38400 baud +** Wakeup condition : Idle line wakeup +** Stop in wait mode : no +** Idle line mode : Starts after start bit +** Transmitter output : Not inverted +** Receiver input : Not inverted +** Break generation length : 10/11 bits +** Receiver : Enabled +** RxD : PTD2/LLWU_P13/SPI0_SOUT/UART2_RX +** RxD pin signal : UART_SWD_RX +** Transmitter : Enabled +** TxD : PTD3/SPI0_SIN/UART2_TX +** TxD pin signal : UART_SWD_TX +** Flow control : None +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnBlockSent : Enabled +** OnBlockReceived : Enabled +** OnTxComplete : Disabled +** OnError : Enabled +** OnBreak : Enabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); +** SendBlock - LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** ReceiveBlock - LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData... +** GetError - LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr,... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ASerialLdd2.h +** @version 01.12 +** @brief +** This component "Serial_LDD" implements an asynchronous serial +** communication. The component supports different settings of +** parity, word width, stop-bit and communication speed, +** user can select interrupt or polling handler. +** Communication speed can be changed also in runtime. +** The component requires one on-chip asynchronous serial communication channel. +*/ +/*! +** @addtogroup ASerialLdd2_module ASerialLdd2 module documentation +** @{ +*/ + +#ifndef __ASerialLdd2_H +#define __ASerialLdd2_H + +/* MODULE ASerialLdd2. */ + + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define ASerialLdd2_PRPH_BASE_ADDRESS 0x4006C000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define ASerialLdd2_Init_METHOD_ENABLED /*!< Init method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_SendBlock_METHOD_ENABLED /*!< SendBlock method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_ReceiveBlock_METHOD_ENABLED /*!< ReceiveBlock method of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_GetError_METHOD_ENABLED /*!< GetError method of the component ASerialLdd2 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define ASerialLdd2_OnBlockReceived_EVENT_ENABLED /*!< OnBlockReceived event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnBlockSent_EVENT_ENABLED /*!< OnBlockSent event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnBreak_EVENT_ENABLED /*!< OnBreak event of the component ASerialLdd2 is enabled (generated) */ +#define ASerialLdd2_OnError_EVENT_ENABLED /*!< OnError event of the component ASerialLdd2 is enabled (generated) */ + +#define ENABLED_TX_INT 0x01U /*!< TX interrupt enabled */ +#define BREAK_DETECTED 0x02U /*!< Break detected */ +#define TX_COMPLETED 0x04U /*!< Transmission completed */ +#define ENABLE_TX_COMPLETE 0x10U /*!< Enable/Disable of TX complete detection. Used in the polling mode only */ + +/*! Device data structure type */ +typedef struct { + uint16_t SerFlag; /*!< Flags for serial communication */ + LDD_SERIAL_TError ErrFlag; /*!< Error flags mirror of SerFlag */ + uint16_t InpRecvDataNum; /*!< The counter of received characters */ + uint8_t *InpDataPtr; /*!< The buffer pointer for received characters */ + uint16_t InpDataNumReq; /*!< The counter of characters to receive by ReceiveBlock() */ + uint16_t OutSentDataNum; /*!< The counter of sent characters */ + uint8_t *OutDataPtr; /*!< The buffer pointer for data to be transmitted */ + uint16_t OutDataNumReq; /*!< The counter of characters to be send by SendBlock() */ + LDD_TUserData *UserDataPtr; /*!< Pointer to user data */ +} ASerialLdd2_TDeviceData; + +typedef ASerialLdd2_TDeviceData *ASerialLdd2_TDeviceDataPtr ; /*!< Pointer to the device data structure. */ + +/* +** =================================================================== +** Method : ASerialLdd2_Init (component Serial_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Device data structure pointer. +*/ +/* ===================================================================*/ +LDD_TDeviceData* ASerialLdd2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : ASerialLdd2_ReceiveBlock (component Serial_LDD) +*/ +/*! +** @brief +** Specifies the number of data to receive. The method returns +** ERR_BUSY until the specified number of characters is +** received. Method [CancelBlockReception] can be used to +** cancel a running receive operation. If a receive operation +** is not in progress (the method was not called or a previous +** operation has already finished) all received characters will +** be lost without any notification. To prevent the loss of +** data call the method immediately after the last receive +** operation has finished (e.g. from the [OnBlockReceived] +** event). This method finishes immediately after calling it - +** it doesn't wait the end of data reception. Use event +** [OnBlockReceived] to check the end of data reception or +** method GetReceivedDataNum to check the state of receiving. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer where +** received characters will be stored. In case +** of 8bit character width each character in +** buffer occupies 1 byte. In case of 9 and +** more bit long character width each +** character in buffer occupies 2 bytes. +** @param +** Size - Number of characters to receive +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous receive request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_ReceiveBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd2_SendBlock (component Serial_LDD) +*/ +/*! +** @brief +** Sends a block of characters. The method returns ERR_BUSY +** when the previous block transmission is not completed. +** Method [CancelBlockTransmission] can be used to cancel a +** transmit operation. This method is available only if the +** transmitter property is enabled. This method finishes +** immediately after calling it - it doesn't wait the end of +** data transmission. Use event [OnBlockSent] to check the end +** of data transmission or method GetSentDataNum to check the +** state of sending. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** BufferPtr - Pointer to a buffer from where +** data will be sent. In case of 8bit +** character width each character in buffer +** occupies 1 byte. In case of 9 and more bit +** long character width each character in +** buffer occupies 2 bytes. +** @param +** Size - Number of characters in the buffer. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration. +** ERR_PARAM_SIZE - Parameter Size is out of +** expected range. +** ERR_DISABLED - The component or device is +** disabled. +** ERR_BUSY - The previous transmit request is +** pending. +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_SendBlock(LDD_TDeviceData *DeviceDataPtr, LDD_TData *BufferPtr, uint16_t Size); + +/* +** =================================================================== +** Method : ASerialLdd2_Interrupt (component Serial_LDD) +** +** Description : +** The ISR function handling the device receive/transmit +** interrupt. Calls InterruptTX/InterruptRX methods. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(ASerialLdd2_Interrupt); + +/* +** =================================================================== +** Method : ASerialLdd2_GetError (component Serial_LDD) +*/ +/*! +** @brief +** This method returns a set of asserted flags. The flags are +** accumulated in the set. After calling this method the set is +** returned and cleared. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ErrorPtr - A pointer to the returned set of +** error flags: +** LDD_SERIAL_RX_OVERRUN - Receiver overrun. +** LDD_SERIAL_PARITY_ERROR - Parity error +** (only if HW supports parity feature). +** LDD_SERIAL_FRAMING_ERROR - Framing error. +** LDD_SERIAL_NOISE_ERROR - Noise error. +** @return +** - Error code (if GetError did not succeed), +** possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active clock configuration +** ERR_DISABLED - Component is disabled +*/ +/* ===================================================================*/ +LDD_TError ASerialLdd2_GetError(LDD_TDeviceData *DeviceDataPtr, LDD_SERIAL_TError *ErrorPtr); + +/* END ASerialLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __ASerialLdd2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.c new file mode 100644 index 0000000..fe937c8 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.c @@ -0,0 +1,252 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +/* MODULE BitIoLdd1. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd1_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd1_TDeviceData *BitIoLdd1_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd1_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=1 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x01); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~1 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x01)); + /* Initialization of Port Control register */ + /* PORTD_PCR0: ISF=0,MUX=1 */ + PORTD_PCR0 = (uint32_t)((PORTD_PCR0 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd1_MODULE_BASE_ADDRESS) & BitIoLdd1_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_TogglePortDataOutputMask(BitIoLdd1_MODULE_BASE_ADDRESS, BitIoLdd1_PORT_MASK); +} + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.h new file mode 100644 index 0000000..5fb37a7 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd1.h @@ -0,0 +1,236 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd1 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd1.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd1_module BitIoLdd1 module documentation +** @{ +*/ + +#ifndef __BitIoLdd1_H +#define __BitIoLdd1_H + +/* MODULE BitIoLdd1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd1_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd1_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd1_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd1_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd1 is enabled (generated) */ +#define BitIoLdd1_NegVal_METHOD_ENABLED /*!< NegVal method of the component BitIoLdd1 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd1_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd1_PORT_MASK 0x01U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd1_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd1_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd1_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd1_NegVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.c new file mode 100644 index 0000000..e9e0269 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.c @@ -0,0 +1,186 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd2 +** Pin for I/O : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/I2S0_MCLK +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd2.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd2_module BitIoLdd2 module documentation +** @{ +*/ + +/* MODULE BitIoLdd2. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd2_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd2_TDeviceData *BitIoLdd2_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd2_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd2_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as input */ + /* GPIOC_PDDR: PDD&=~0x40 */ + GPIOC_PDDR &= (uint32_t)~(uint32_t)(GPIO_PDDR_PDD(0x40)); + /* Initialization of Port Control register */ + /* PORTC_PCR6: ISF=0,MUX=1 */ + PORTC_PCR6 = (uint32_t)((PORTC_PCR6 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd2_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd2_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataInput(BitIoLdd2_MODULE_BASE_ADDRESS) & BitIoLdd2_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* END BitIoLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.h new file mode 100644 index 0000000..4ae9f38 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd2.h @@ -0,0 +1,182 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd2 +** Pin for I/O : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/I2S0_MCLK +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd2.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd2_module BitIoLdd2 module documentation +** @{ +*/ + +#ifndef __BitIoLdd2_H +#define __BitIoLdd2_H + +/* MODULE BitIoLdd2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd2_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd2_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd2_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd2_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd2 is enabled (generated) */ +#define BitIoLdd2_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd2 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd2_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd2_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd2_PORT_MASK 0x40U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd2_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd2_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd2_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.c new file mode 100644 index 0000000..6122007 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.c @@ -0,0 +1,186 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd3.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd3 +** Pin for I/O : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd3_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd3_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd3.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd3_module BitIoLdd3 module documentation +** @{ +*/ + +/* MODULE BitIoLdd3. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd3.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd3_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd3_TDeviceData *BitIoLdd3_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd3_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd3_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd3_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd3_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as input */ + /* GPIOC_PDDR: PDD&=~0x80 */ + GPIOC_PDDR &= (uint32_t)~(uint32_t)(GPIO_PDDR_PDD(0x80)); + /* Initialization of Port Control register */ + /* PORTC_PCR7: ISF=0,MUX=1 */ + PORTC_PCR7 = (uint32_t)((PORTC_PCR7 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd3_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd3_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd3_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataInput(BitIoLdd3_MODULE_BASE_ADDRESS) & BitIoLdd3_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* END BitIoLdd3. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.h new file mode 100644 index 0000000..f024785 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd3.h @@ -0,0 +1,182 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd3.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd3 +** Pin for I/O : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd3_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd3_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd3.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd3_module BitIoLdd3 module documentation +** @{ +*/ + +#ifndef __BitIoLdd3_H +#define __BitIoLdd3_H + +/* MODULE BitIoLdd3. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd3_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd3_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd3_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd3_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd3 is enabled (generated) */ +#define BitIoLdd3_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd3 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd3_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd3_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd3_PORT_MASK 0x80U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd3_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd3_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd3_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd3_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd3. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd3_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.c new file mode 100644 index 0000000..daf2fdb --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.c @@ -0,0 +1,186 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd4.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd4 +** Pin for I/O : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/CMP0_OUT +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd4.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd4_module BitIoLdd4 module documentation +** @{ +*/ + +/* MODULE BitIoLdd4. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd4.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd4_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd4_TDeviceData *BitIoLdd4_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd4_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd4_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd4_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as input */ + /* GPIOC_PDDR: PDD&=~0x20 */ + GPIOC_PDDR &= (uint32_t)~(uint32_t)(GPIO_PDDR_PDD(0x20)); + /* Initialization of Port Control register */ + /* PORTC_PCR5: ISF=0,MUX=1 */ + PORTC_PCR5 = (uint32_t)((PORTC_PCR5 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd4_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd4_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataInput(BitIoLdd4_MODULE_BASE_ADDRESS) & BitIoLdd4_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* END BitIoLdd4. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.h new file mode 100644 index 0000000..dc51a39 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd4.h @@ -0,0 +1,182 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd4.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd4 +** Pin for I/O : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/CMP0_OUT +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd4.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd4_module BitIoLdd4 module documentation +** @{ +*/ + +#ifndef __BitIoLdd4_H +#define __BitIoLdd4_H + +/* MODULE BitIoLdd4. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd4_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd4_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd4_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd4_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd4 is enabled (generated) */ +#define BitIoLdd4_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd4 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd4_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd4_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd4_PORT_MASK 0x20U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd4_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd4_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd4_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd4_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd4. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd4_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.c new file mode 100644 index 0000000..52d31ee --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.c @@ -0,0 +1,186 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd5.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd5 +** Pin for I/O : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/CMP1_OUT +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd5.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd5_module BitIoLdd5 module documentation +** @{ +*/ + +/* MODULE BitIoLdd5. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd5.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd5_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd5_TDeviceData *BitIoLdd5_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd5_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd5_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd5_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as input */ + /* GPIOC_PDDR: PDD&=~0x10 */ + GPIOC_PDDR &= (uint32_t)~(uint32_t)(GPIO_PDDR_PDD(0x10)); + /* Initialization of Port Control register */ + /* PORTC_PCR4: ISF=0,MUX=1 */ + PORTC_PCR4 = (uint32_t)((PORTC_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd5_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd5_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataInput(BitIoLdd5_MODULE_BASE_ADDRESS) & BitIoLdd5_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* END BitIoLdd5. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.h new file mode 100644 index 0000000..95f36b3 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd5.h @@ -0,0 +1,182 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd5.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd5 +** Pin for I/O : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/CMP1_OUT +** Pin signal : +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd5.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd5_module BitIoLdd5 module documentation +** @{ +*/ + +#ifndef __BitIoLdd5_H +#define __BitIoLdd5_H + +/* MODULE BitIoLdd5. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd5_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd5_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd5_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd5_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd5 is enabled (generated) */ +#define BitIoLdd5_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd5 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd5_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd5_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd5_PORT_MASK 0x10U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd5_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd5_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd5_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd5_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd5. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd5_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.c new file mode 100644 index 0000000..ac7507e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd6.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd6 +** Pin for I/O : TSI0_CH9/PTB16/UART0_RX/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd6.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd6_module BitIoLdd6 module documentation +** @{ +*/ + +/* MODULE BitIoLdd6. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd6.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd6_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd6_TDeviceData *BitIoLdd6_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd6_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd6_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd6_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOB_PDDR: PDD|=0x00010000 */ + GPIOB_PDDR |= GPIO_PDDR_PDD(0x00010000); + /* Set initialization value */ + /* GPIOB_PDOR: PDO&=~0x00010000 */ + GPIOB_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x00010000)); + /* Initialization of Port Control register */ + /* PORTB_PCR16: ISF=0,MUX=1 */ + PORTB_PCR16 = (uint32_t)((PORTB_PCR16 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd6_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd6_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd6_MODULE_BASE_ADDRESS) & BitIoLdd6_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd6_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd6_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd6_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd6_MODULE_BASE_ADDRESS, BitIoLdd6_PORT_MASK); +} + +/* END BitIoLdd6. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.h new file mode 100644 index 0000000..8a4d1d1 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd6.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd6.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd6 +** Pin for I/O : TSI0_CH9/PTB16/UART0_RX/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd6.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd6_module BitIoLdd6 module documentation +** @{ +*/ + +#ifndef __BitIoLdd6_H +#define __BitIoLdd6_H + +/* MODULE BitIoLdd6. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd6_PRPH_BASE_ADDRESS 0x400FF040U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd6_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd6_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd6_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd6 is enabled (generated) */ +#define BitIoLdd6_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd6 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd6_MODULE_BASE_ADDRESS PTB_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd6_PORTCONTROL_BASE_ADDRESS PORTB_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd6_PORT_MASK 0x00010000U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd6_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd6_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd6_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd6_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd6_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd6_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd6_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd6. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd6_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.c new file mode 100644 index 0000000..b93a499 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd7.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd7 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/I2S0_TX_FS +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd7.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd7_module BitIoLdd7 module documentation +** @{ +*/ + +/* MODULE BitIoLdd7. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd7.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd7_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd7_TDeviceData *BitIoLdd7_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd7_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd7_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd7_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOC_PDDR: PDD|=4 */ + GPIOC_PDDR |= GPIO_PDDR_PDD(0x04); + /* Set initialization value */ + /* GPIOC_PDOR: PDO&=~4 */ + GPIOC_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x04)); + /* Initialization of Port Control register */ + /* PORTC_PCR2: ISF=0,MUX=1 */ + PORTC_PCR2 = (uint32_t)((PORTC_PCR2 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd7_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd7_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd7_MODULE_BASE_ADDRESS) & BitIoLdd7_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd7_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd7_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd7_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd7_MODULE_BASE_ADDRESS, BitIoLdd7_PORT_MASK); +} + +/* END BitIoLdd7. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.h new file mode 100644 index 0000000..502a99d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd7.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd7.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd7 +** Pin for I/O : ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/I2S0_TX_FS +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd7.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd7_module BitIoLdd7 module documentation +** @{ +*/ + +#ifndef __BitIoLdd7_H +#define __BitIoLdd7_H + +/* MODULE BitIoLdd7. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd7_PRPH_BASE_ADDRESS 0x400FF080U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd7_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd7_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd7_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd7 is enabled (generated) */ +#define BitIoLdd7_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd7 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd7_MODULE_BASE_ADDRESS PTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd7_PORTCONTROL_BASE_ADDRESS PORTC_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd7_PORT_MASK 0x04U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd7_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd7_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd7_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd7_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd7_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd7_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd7_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd7. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd7_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.c new file mode 100644 index 0000000..9ed36d5 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.c @@ -0,0 +1,266 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd8.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd8 +** Pin for I/O : ADC0_SE13/TSI0_CH8/PTB3/I2C0_SDA/UART0_CTS_b/UART0_COL_b/FTM0_FLT0 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd8.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd8_module BitIoLdd8 module documentation +** @{ +*/ + +/* MODULE BitIoLdd8. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd8.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd8_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd8_TDeviceData *BitIoLdd8_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd8_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd8_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd8_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOB_PDDR: PDD|=8 */ + GPIOB_PDDR |= GPIO_PDDR_PDD(0x08); + /* Set initialization value */ + /* GPIOB_PDOR: PDO&=~8 */ + GPIOB_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x08)); + /* Initialization of Port Control register */ + /* PORTB_PCR3: ISF=0,MUX=1 */ + PORTB_PCR3 = (uint32_t)((PORTB_PCR3 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd8_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd8_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd8_MODULE_BASE_ADDRESS) & BitIoLdd8_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd8_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + if (Val) { + GPIO_PDD_SetPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); + } else { /* !Val */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); + } /* !Val */ +} + +/* +** =================================================================== +** Method : BitIoLdd8_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd8_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd8_MODULE_BASE_ADDRESS, BitIoLdd8_PORT_MASK); +} + +/* END BitIoLdd8. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.h new file mode 100644 index 0000000..b332cb6 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd8.h @@ -0,0 +1,246 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd8.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd8 +** Pin for I/O : ADC0_SE13/TSI0_CH8/PTB3/I2C0_SDA/UART0_CTS_b/UART0_COL_b/FTM0_FLT0 +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : no +** Contents : +** Init - LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); +** PutVal - void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); +** ClrVal - void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd8.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd8_module BitIoLdd8 module documentation +** @{ +*/ + +#ifndef __BitIoLdd8_H +#define __BitIoLdd8_H + +/* MODULE BitIoLdd8. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd8_PRPH_BASE_ADDRESS 0x400FF040U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd8_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd8_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd8_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_PutVal_METHOD_ENABLED /*!< PutVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd8 is enabled (generated) */ +#define BitIoLdd8_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd8 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd8_MODULE_BASE_ADDRESS PTB_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd8_PORTCONTROL_BASE_ADDRESS PORTB_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd8_PORT_MASK 0x08U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd8_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd8_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd8_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_PutVal (component BitIO_LDD) +*/ +/*! +** @brief +** The specified output value is set. If the direction is +** input, the component saves the value to a memory or a +** register and this value will be written to the pin after +** switching to the output mode (using SetDir(TRUE); +** see Safe mode +** property for limitations). If the direction is output, +** it writes the value to the pin. (Method is available only if +** the direction = output or +** input/output). +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @param +** Val - Output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +void BitIoLdd8_PutVal(LDD_TDeviceData *DeviceDataPtr, bool Val); + +/* +** =================================================================== +** Method : BitIoLdd8_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd8_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd8_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd8. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd8_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.c new file mode 100644 index 0000000..9c0ca6e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.c @@ -0,0 +1,252 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd9.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd9 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd9_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd9_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd9_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd9.c +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd9_module BitIoLdd9 module documentation +** @{ +*/ + +/* MODULE BitIoLdd9. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "BitIoLdd9.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TUserData *UserDataPtr; /* Pointer to user data */ +} BitIoLdd9_TDeviceData; /* Device data structure type */ + +typedef BitIoLdd9_TDeviceData *BitIoLdd9_TDeviceDataPtr ; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static BitIoLdd9_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* +** =================================================================== +** Method : BitIoLdd9_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + BitIoLdd9_TDeviceDataPtr DeviceDataPrv; + + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Configure pin as output */ + /* GPIOD_PDDR: PDD|=0x10 */ + GPIOD_PDDR |= GPIO_PDDR_PDD(0x10); + /* Set initialization value */ + /* GPIOD_PDOR: PDO&=~0x10 */ + GPIOD_PDOR &= (uint32_t)~(uint32_t)(GPIO_PDOR_PDO(0x10)); + /* Initialization of Port Control register */ + /* PORTD_PCR4: ISF=0,MUX=1 */ + PORTD_PCR4 = (uint32_t)((PORTD_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x06) + )) | (uint32_t)( + PORT_PCR_MUX(0x01) + )); + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_BitIoLdd9_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); +} +/* +** =================================================================== +** Method : BitIoLdd9_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr) +{ + uint32_t PortData; /* Port data masked according to the bit used */ + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PortData = GPIO_PDD_GetPortDataOutput(BitIoLdd9_MODULE_BASE_ADDRESS) & BitIoLdd9_PORT_MASK; + return (PortData != 0U) ? (bool)TRUE : (bool)FALSE; +} + +/* +** =================================================================== +** Method : BitIoLdd9_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_ClrVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_ClearPortDataOutputMask(BitIoLdd9_MODULE_BASE_ADDRESS, BitIoLdd9_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd9_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_SetVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_SetPortDataOutputMask(BitIoLdd9_MODULE_BASE_ADDRESS, BitIoLdd9_PORT_MASK); +} + +/* +** =================================================================== +** Method : BitIoLdd9_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_NegVal(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + GPIO_PDD_TogglePortDataOutputMask(BitIoLdd9_MODULE_BASE_ADDRESS, BitIoLdd9_PORT_MASK); +} + +/* END BitIoLdd9. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.h new file mode 100644 index 0000000..6466c5d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/BitIoLdd9.h @@ -0,0 +1,236 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : BitIoLdd9.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO_LDD +** Version : Component 01.033, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +** Settings : +** Component name : BitIoLdd9 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Auto initialization : yes +** Safe mode : yes +** Contents : +** Init - LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); +** GetVal - bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); +** ClrVal - void BitIoLdd9_ClrVal(LDD_TDeviceData *DeviceDataPtr); +** SetVal - void BitIoLdd9_SetVal(LDD_TDeviceData *DeviceDataPtr); +** NegVal - void BitIoLdd9_NegVal(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file BitIoLdd9.h +** @version 01.03 +** @brief +** The HAL BitIO component provides a low level API for unified +** access to general purpose digital input/output pins across +** various device designs. +** +** RTOS drivers using HAL BitIO API are simpler and more +** portable to various microprocessors. +*/ +/*! +** @addtogroup BitIoLdd9_module BitIoLdd9 module documentation +** @{ +*/ + +#ifndef __BitIoLdd9_H +#define __BitIoLdd9_H + +/* MODULE BitIoLdd9. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "IO_Map.h" +#include "GPIO_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define BitIoLdd9_PRPH_BASE_ADDRESS 0x400FF0C0U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define BitIoLdd9_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_BitIoLdd9_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define BitIoLdd9_Init_METHOD_ENABLED /*!< Init method of the component BitIoLdd9 is enabled (generated) */ +#define BitIoLdd9_GetVal_METHOD_ENABLED /*!< GetVal method of the component BitIoLdd9 is enabled (generated) */ +#define BitIoLdd9_ClrVal_METHOD_ENABLED /*!< ClrVal method of the component BitIoLdd9 is enabled (generated) */ +#define BitIoLdd9_SetVal_METHOD_ENABLED /*!< SetVal method of the component BitIoLdd9 is enabled (generated) */ +#define BitIoLdd9_NegVal_METHOD_ENABLED /*!< NegVal method of the component BitIoLdd9 is enabled (generated) */ + +/* Definition of implementation constants */ +#define BitIoLdd9_MODULE_BASE_ADDRESS PTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd9_PORTCONTROL_BASE_ADDRESS PORTD_BASE_PTR /*!< Name of macro used as the base address */ +#define BitIoLdd9_PORT_MASK 0x10U /*!< Mask of the allocated pin from the port */ + + + +/* +** =================================================================== +** Method : BitIoLdd9_Init (component BitIO_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the "Enable +** in init. code" is set to "yes" value then the device is also +** enabled(see the description of the Enable() method). In this +** case the Enable() method is not necessary and needn't to be +** generated. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* BitIoLdd9_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd9_GetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Returns the input/output value. If the direction is [input] +** then the input value of the pin is read and returned. If the +** direction is [output] then the last written value is read +** and returned (see property for limitations). +** This method cannot be disabled if direction is [input]. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by method. +** @return +** - Input or output value. Possible values: +** - logical "0" (Low level) +** - logical "1" (High level) +*/ +/* ===================================================================*/ +bool BitIoLdd9_GetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd9_ClrVal (component BitIO_LDD) +*/ +/*! +** @brief +** Clears (set to zero) the output value. It is equivalent to +** the [PutVal(FALSE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_ClrVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd9_SetVal (component BitIO_LDD) +*/ +/*! +** @brief +** Sets (to one) the output value. It is equivalent to the +** [PutVal(TRUE)]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_SetVal(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : BitIoLdd9_NegVal (component BitIO_LDD) +*/ +/*! +** @brief +** Negates (inverts) the output value. It is equivalent to the +** [PutVal(!GetVal())]. This method is available only if the +** direction = _[output]_ or _[input/output]_. +** @param +** DeviceDataPtr - Pointer to device data +** structure returned by method. +*/ +/* ===================================================================*/ +void BitIoLdd9_NegVal(LDD_TDeviceData *DeviceDataPtr); + +/* END BitIoLdd9. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __BitIoLdd9_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.c new file mode 100644 index 0000000..7969a55 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.c @@ -0,0 +1,1487 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:38, # CodeGen: 15 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD>" +** Project Name : TinyK20 OpenPnP Feeder +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Disabled +** Utility : UTIL1 +** Default Serial : Enabled +** Console Interface : AS1 +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + +/* MODULE CLS1. */ +#include /* for isalnum*/ + +#include "CLS1.h" +#include "XF1.h" +#include "UTIL1.h" +#include "CS1.h" + #include "WAIT1.h" + +#if CLS1_DEFAULT_SERIAL + #include CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE +#endif + + +uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +#if CLS1_HISTORY_ENABLED + static uint8_t CLS1_history[CLS1_NOF_HISTORY][CLS1_HIST_LEN]; /* History buffers */ + static uint8_t CLS1_history_index = 0; /* Selected command */ +#endif +#if CLS1_ECHO_ENABLED + static bool CLS1_EchoEnabled = TRUE; +#endif + +#if CLS1_CONFIG_USE_MUTEX + #include "FreeRTOS.h" + #include "task.h" + #include "semphr.h" +#endif + +#ifdef __HC08__ + #pragma MESSAGE DISABLE C3303 /* implicit concatenation of strings */ +#endif +#if CLS1_CONFIG_USE_MUTEX + static SemaphoreHandle_t ShellSem = NULL; /* Semaphore to protect shell SCI access */ +#endif + +#if CLS1_DEFAULT_SERIAL + CLS1_ConstStdIOType CLS1_stdio = + { + (CLS1_StdIO_In_FctType)CLS1_ReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)CLS1_SendChar, /* stderr */ + CLS1_KeyPressed /* if input is not empty */ + }; + static CLS1_ConstStdIOType *CLS1_currStdIO = &CLS1_stdio; +#else + static CLS1_ConstStdIOType *CLS1_currStdIO = NULL; /* needs to be set through CLS1_SetStdio(); */ +#endif +/* Internal method prototypes */ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io); + +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + io(ch); +} + +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +/*! + * \brief Prints a string using I/O callbacks + * \param[in] str String (zero terminated) to be printed + * \param[in] io I/O function to be used for printing + */ +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io) +{ + if (io==NULL) { + return; + } + while(*str!='\0') { + io(*str++); + } +} + +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-1234567890")]; + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("1234567890")]; + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-12345")]; + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("12345")]; + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("123")]; + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io) +{ + unsigned char buf[sizeof("-123")]; + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + CLS1_SendStr(buf, io); +} + +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io) +{ + if (UTIL1_strcmp((char*)cmd, CLS1_CMD_HELP)==0 || UTIL1_strcmp((char*)cmd, "CLS1 help")==0) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROJECT_NAME_STRING, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendStr((unsigned char*)CLS1_DASH_LINE, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)"CLS1", (const unsigned char*)"Group of CLS1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (const unsigned char*)"Print help or status information\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendHelpStr((unsigned char*)" echo (on|off)", (const unsigned char*)"Turn echo on or off\r\n", io->stdOut); +#endif + *handled = TRUE; + return ERR_OK; +#if CLS1_ECHO_ENABLED + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo on")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = TRUE; + return ERR_OK; + } else if ((UTIL1_strcmp((char*)cmd, "CLS1 echo off")==0)) { + *handled = TRUE; + CLS1_EchoEnabled = FALSE; + return ERR_OK; +#endif + } else if ((UTIL1_strcmp((char*)cmd, CLS1_CMD_STATUS)==0) || (UTIL1_strcmp((char*)cmd, "CLS1 status")==0)) { + *handled = TRUE; + return CLS1_PrintStatus(io); + } + return ERR_OK; /* no error */ +} + +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); /* ensure that there is a new line */ + CLS1_SendStr((unsigned char*)CLS1_CONFIG_PROMPT_STRING, io->stdOut); +} + +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev) +{ + *isPrev = FALSE; +#if CLS1_HISTORY_ENABLED + if ( cmdBufIdx==0 /* first character on command line */ + || (UTIL1_strcmp((const char*)cmdBuf, (const char*)CLS1_history[CLS1_history_index])==0) /* pressing prev/next character on previous history element */ + ) + { + if (ch==CLS1_HISTORY_PREV_CHAR) { + *isPrev = TRUE; + return TRUE; + } else if (ch==CLS1_HISTORY_NEXT_CHAR) { + *isPrev = FALSE; + return TRUE; + } + } +#if 0 + if (cmdBufIdx==0 || cmdBufIdx==2) { /* accept only first character or sequence as history sequence */ + if (cmdBufIdx==2 && cmdBuf[0]==0x1b && cmdBuf[1]==0x5b) { + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (cmdBuf[2]==0x41 /* up */ || cmdBuf[2]==0x44 /* left */) { + *isPrev = TRUE; + return TRUE; + } else if (cmdBuf[2]==0x42 /* down */ || cmdBuf[2]==0x43 /* right */) { + *isPrev = FALSE; + return TRUE; + } + } + /* \todo: handle TAB and SHIFT-TAB */ + } +#endif +#else + (void)ch; /* not used */ + (void)cmdBuf; /* not used */ + (void)cmdBufIdx; /* not used */ +#endif + return FALSE; +} + +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io) +{ + uint8_t c; + bool isBackwardHistory; + + if (io->keyPressed()) { + for(;;) { /* while not '\r' or '\n' */ + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + if (c=='\0') { /* nothing in rx buffer? Something is wrong... */ + break; /* get out of loop */ + } + if (c=='\b' || c=='\177') { /* check for backspace */ + if (buf > bufStart) { /* Avoid buffer underflow */ +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut('\b'); /* delete character on terminal */ + io->stdOut(' '); + io->stdOut('\b'); + } +#endif + buf--; /* delete last character in buffer */ + *buf = '\0'; + bufSize++; + } + } else if (CLS1_IsHistoryCharacter(c, bufStart, (size_t)(buf-bufStart), &isBackwardHistory)) { +#if CLS1_HISTORY_ENABLED + uint8_t cBuf[3]={'\0','\0','\0'}, cBufIdx = 0; + bool prevInHistory; +#endif + + while (c!='\0') { /* empty the rx buffer (escape sequence) */ +#if CLS1_HISTORY_ENABLED + cBuf[cBufIdx] = c; + cBufIdx++; + if (cBufIdx==sizeof(cBuf)) { + cBufIdx = 0; /* ring buffer */ + } +#endif + c = '\0'; /* initialize character */ + io->stdIn(&c); /* read character */ + } +#if CLS1_HISTORY_ENABLED + /* if not an alphanumeric switch to history */ + prevInHistory = cBufIdx==0 && cBuf[0]==0x1b && cBuf[1]==0x5b && (cBuf[2]==0x41 /*up*/ || cBuf[2]==0x44 /*left*/); + /* up: 0x27 0x5b 0x41 + * down: 0x27 0x5b 0x42 + * right: 0x27 0x5b 0x43 + * left: 0x27 0x5b 0x44 + */ + if (prevInHistory) { + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + CLS1_history_index++; /* update the index */ + if (CLS1_history_index==CLS1_NOF_HISTORY) { + CLS1_history_index = 0; + } + } else { + if (CLS1_history_index==0) { + CLS1_history_index = (CLS1_NOF_HISTORY-1); + } else { + CLS1_history_index--; + } + UTIL1_strcpy(bufStart, CLS1_HIST_LEN, CLS1_history[CLS1_history_index]); + } + bufSize = bufSize + buf - bufStart - UTIL1_strlen((const char*)bufStart); /* update the buffer */ + buf = bufStart + UTIL1_strlen((const char*)bufStart); +#endif +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + CLS1_PrintPrompt(io); + CLS1_SendStr(bufStart, io->stdOut); + } +#endif + } else { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + io->stdOut(c); /* echo character */ + } +#endif + *buf = (uint8_t)c; /* append character to the string */ + buf++; + bufSize--; + if ((c=='\r') || (c=='\n')) { +#if CLS1_ECHO_ENABLED + if (CLS1_EchoEnabled) { + CLS1_SendStr((unsigned char*)"\n", io->stdOut); + } +#endif +#if CLS1_HISTORY_ENABLED + if ((bufStart[0] != '\0') && (bufStart[0] != '\r') && (bufStart[0] != '\n')) { + int i; + + for(i=CLS1_NOF_HISTORY-1; i>0;i--) { + UTIL1_strcpy(CLS1_history[i], CLS1_HIST_LEN, CLS1_history[i-1]); /* move previous commands */ + } + CLS1_history_index = 0; /* update the history with the current command */ + UTIL1_strcpy(CLS1_history[0], CLS1_HIST_LEN, bufStart); /* add the current command to the history */ + if (buf-bufStart <= CLS1_HIST_LEN) { /* size check */ + CLS1_history[0][buf-bufStart-1] = '\0'; + } else { + CLS1_history[0][CLS1_HIST_LEN-1] = '\0'; + } + } +#endif + break; + } + if (bufSize <= 1) { /* buffer full */ + break; + } + } + } /* for */ + *buf = '\0'; /* zero terminate string */ + return TRUE; + } else { + return FALSE; + } +} + +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io) +{ + CLS1_SendStatusStr((const unsigned char*)"CLS1", (const unsigned char*)"\r\n", io->stdOut); + CLS1_SendStatusStr((const unsigned char*)" Build", (const unsigned char*)__DATE__, io->stdOut); + CLS1_SendStr((unsigned char*)" ", io->stdOut); + CLS1_SendStr((unsigned char*)__TIME__, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); +#if CLS1_ECHO_ENABLED + CLS1_SendStatusStr((const unsigned char*)" echo", CLS1_EchoEnabled?(const unsigned char*)"On\r\n":(const unsigned char*)"Off\r\n", io->stdOut); +#endif + return ERR_OK; +} + +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io) +{ + CLS1_SendStr((unsigned char*)"*** Failed or unknown command: ", io->stdErr); + CLS1_SendStr(cmd, io->stdErr); + CLS1_SendStr((unsigned char*)"\r\n", io->stdErr); + CLS1_SendStr((unsigned char*)"*** Type ", io->stdErr); + CLS1_SendStr((unsigned char*)CLS1_CMD_HELP, io->stdErr); + CLS1_SendStr((unsigned char*)" to get a list of available commands\r\n", io->stdErr); +} + +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable) +{ + uint8_t res = ERR_OK; + + if (parserTable==NULL) { /* no table??? */ + return ERR_FAILED; + } + if (io==NULL) { /* no IO handler??? */ + return ERR_FAILED; + } + /* iterate through all parser functions in table */ + while(*parserTable!=NULL) { + if ((*parserTable)(cmd, handled, io)!=ERR_OK) { + res = ERR_FAILED; + } + parserTable++; + } + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + uint8_t res = ERR_OK; + bool handled; +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + bool silentPrefix = FALSE; +#endif +#if CLS1_CONFIG_MULTI_CMD_ENABLED + uint8_t buf[CLS1_CONFIG_MULTI_CMD_SIZE]; + uint8_t i; + bool parseBuffer, finished; +#endif + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + if (*cmd=='\0') { /* empty command */ + return ERR_OK; + } +#if CLS1_CONFIG_MULTI_CMD_ENABLED + parseBuffer = FALSE; + finished = FALSE; + i = 0; + for(;;) { /* breaks */ + if (i>sizeof(buf)-2) { + res = ERR_FAILED; + CLS1_PrintCommandFailed(buf, io); + break; /* buffer overflow */ + } + buf[i] = *cmd; + cmd++; i++; + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (i==1 && buf[0]==CLS1_SILENT_PREFIX_CHAR) { /* first character is silent character */ + silentPrefix |= (bool)(buf[0]==CLS1_SILENT_PREFIX_CHAR); + buf[0] = *cmd; /* skip silent character */ + cmd++; + } + #endif + if (buf[i-1] == CLS1_CONFIG_MULTI_CMD_CHAR) { /* found separator */ + buf[i-1] = '\0'; + parseBuffer = TRUE; + } else if (buf[i-1]=='\0') { + parseBuffer = TRUE; + finished = TRUE; + } + if (parseBuffer) { + handled = FALSE; + res = CLS1_IterateTable(buf, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command, or error? */ + CLS1_PrintCommandFailed(buf, io); + res = ERR_FAILED; + } + parseBuffer = FALSE; + i = 0; /* restart */ + } + if (finished) { + break; /* get out of loop */ + } + } /* for */ +#else + #if CLS1_SILENT_PREFIX_CHAR_ENABLED + silentPrefix = (bool)(*cmd==CLS1_SILENT_PREFIX_CHAR); + if (silentPrefix) { + cmd++; /* skip silent character */ + } + #endif + handled = FALSE; + res = CLS1_IterateTable(cmd, &handled, io, parseCallback); /* iterate through all parser functions in table */ + if (!handled || res!=ERR_OK) { /* no handler has handled the command? */ + CLS1_PrintCommandFailed(cmd, io); + res = ERR_FAILED; + } +#endif +#if CLS1_SILENT_PREFIX_CHAR_ENABLED + if (!silentPrefix && !silent) { + CLS1_PrintPrompt(io); + } +#else + if (!silent) { + CLS1_PrintPrompt(io); + } +#endif + return res; +} + +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ParseWithCommandTableExt(cmd, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio) +{ + CLS1_currStdIO = stdio; + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void) +{ + return CLS1_currStdIO; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent) +{ + /* IMPORTANT NOTE: this function *appends* to the buffer, so the buffer needs to be initialized first! */ + uint8_t res = ERR_OK; + size_t len; + + if (io==NULL) { /* no I/O handler? */ + return ERR_FAILED; + } + len = UTIL1_strlen((const char*)cmdBuf); + if (CLS1_ReadLine(cmdBuf, cmdBuf+len, cmdBufSize-len, io)) { + len = UTIL1_strlen((const char*)cmdBuf); /* length of buffer string */ + if (len==0) { /* error case */ + return ERR_FAILED; + } else if (len==1 && (cmdBuf[0]=='\n' || cmdBuf[0]=='\r')) { /* eat preceding newline characters */ + cmdBuf[0] = '\0'; + } + if (len>=cmdBufSize-1) { /* buffer overflow? Parse what we have, will be likely return an error */ + (void)CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + res = ERR_OVERFLOW; + } else if (cmdBuf[len-1]=='\n' || cmdBuf[len-1]=='\r') { /* line end: parse command */ + cmdBuf[len-1] = '\0'; /* remove line end character for parser */ + res = CLS1_ParseWithCommandTableExt(cmdBuf, io, parseCallback, silent); + cmdBuf[0] = '\0'; /* start again */ + } else { + /* continue to append to buffer */ + } + } + return res; +} + +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback) +{ + return CLS1_ReadAndParseWithCommandTableExt(cmdBuf, cmdBufSize, io, parseCallback, FALSE); +} + +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_RequestSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +} + +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReleaseSerial(void) +{ +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ +void* CLS1_GetSemaphore(void) +{ +#if CLS1_CONFIG_USE_MUTEX + return ShellSem; +#else + return NULL; +#endif +} + +/* +** =================================================================== +** Method : SendSeparatedStrings (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SendSeparatedStrings(const uint8_t *strA, const uint8_t *strB, uint8_t tabChar, uint8_t tabPos, CLS1_StdIO_OutErr_FctType io) +{ + /* write command part */ + if (strA!=NULL) { + while(*strA!='\0' && tabPos>0) { + io(*strA++); + tabPos--; + } + } + /* fill up until ';' */ + while(tabPos>0) { + io(' '); + tabPos--; + } + /* write separator */ + io(tabChar); + io(' '); + if (strB!=NULL) { + /* write help text */ + CLS1_SendStr(strB, io); + } +} + +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io) +{ + #define HELP_SEMICOLON_POS 26 /* position of the ';' after the command string */ + SendSeparatedStrings(strCmd, strHelp, ';', HELP_SEMICOLON_POS, io); +} + +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io) +{ + #define STATUS_COLON_POS 13 /* position of the ':' after the item string */ + SendSeparatedStrings(strItem, strStatus, ':', STATUS_COLON_POS, io); +} + +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ +void CLS1_ReadChar(uint8_t *c) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + uint8_t res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif + res = CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME((uint8_t*)c); + if (res==ERR_RXEMPTY) { + /* no character in buffer */ + *c = '\0'; + } +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +#else + *c = '\0'; + return; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendChar(uint8_t ch) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + CLS1_SendCharFct(ch, CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME); +#else + (void)ch; /* avoid compiler warning about unused argument */ +#endif +} + +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +bool CLS1_KeyPressed(void) +{ +#if CLS1_CONFIG_DEFAULT_SERIAL + bool res; + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_DEFAULT_SERIAL + res = (bool)((CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME()==0U) ? FALSE : TRUE); /* true if there are characters in receive buffer */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif + return res; +#else + return FALSE; /* no serial component set up in properties */ +#endif +} + +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CLS1_Init(void) +{ +#if CLS1_CONFIG_USE_MUTEX +#if configSUPPORT_STATIC_ALLOCATION + static StaticSemaphore_t xMutexBuffer; +#endif + bool schedulerStarted; + CS1_CriticalVariable(); + + schedulerStarted = (bool)(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED); + if (!schedulerStarted) { /* FreeRTOS not started yet. We are called in PE_low_level_init(), and interrupts are disabled */ + CS1_EnterCritical(); + } +#if configSUPPORT_STATIC_ALLOCATION + ShellSem = xSemaphoreCreateRecursiveMutexStatic(&xMutexBuffer); +#else + ShellSem = xSemaphoreCreateRecursiveMutex(); +#endif + if (!schedulerStarted) { /* above RTOS call might have enabled interrupts! Make sure we restore the state */ + CS1_ExitCritical(); + } + if (ShellSem==NULL) { /* semaphore creation failed */ + for(;;) {} /* error, not enough memory? */ + } + vQueueAddToRegistry(ShellSem, "CLS1_Sem"); +#endif +#if CLS1_HISTORY_ENABLED + { + int i; + + CLS1_history_index = 0; + for(i=0; i0) { + io(*data++); + dataSize--; + } +} + +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void CLS1_printfPutChar(void *arg, char c) +{ + CLS1_StdIO_OutErr_FctType fct = (CLS1_StdIO_OutErr_FctType)arg; + + fct(c); /* print character */ +} + +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)io->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ +unsigned CLS1_printf(const char *fmt, ...) +{ + va_list args; + unsigned int count = 0; + + va_start(args,fmt); + count = XF1_xvformat(CLS1_printfPutChar, (void*)CLS1_GetStdio()->stdOut, fmt, args); + va_end(args); + return count; +} + +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)) +{ +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + uint8_t res; + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + int timeoutMs = CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif +#endif + +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreTakeRecursive(ShellSem, portMAX_DELAY); +#endif +#if CLS1_CONFIG_BLOCKING_SEND_ENABLED + do { + res = fct((uint8_t)ch); /* Send char, returns error code */ + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if (res==ERR_TXFULL) { + #if CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + WAIT1_WaitOSms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #else + WAIT1_Waitms(CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS); + #endif + } + #endif + #if CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS; + #endif + } while(res==ERR_TXFULL); +#else + (void)fct((uint8_t)ch); /* non blocking send */ +#endif +#if CLS1_CONFIG_USE_MUTEX + (void)xSemaphoreGiveRecursive(ShellSem); +#endif +} + +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io) +{ + #define NOF_BYTES_PER_LINE 32 /* how many bytes are shown on a line. This defines as well the chunk size we read from memory */ + #define MAX_NOF_BYTES_PER_LINE 32 + uint8_t buf[MAX_NOF_BYTES_PER_LINE]; /* this is the chunk of data we get (per line in output) */ + uint8_t str[3*MAX_NOF_BYTES_PER_LINE+((MAX_NOF_BYTES_PER_LINE+1)/8)+1]; /* maximum string for output: + - '3*' because each byte is 2 hex digits plus a space + - '(NOF_BYTES_PER_LINE+1)/8' because we add a space between every 8 byte block + - '+1' for the final zero byte */ + uint32_t addr; + uint8_t res=0, j, bufSize; + uint8_t ch; + + if (endAddrstdErr); + return ERR_RANGE; + } + for(addr=startAddr; addr<=endAddr; /* nothing */ ) { + if (endAddr-addr+1 >= bytesPerLine) { /* read only part of buffer */ + bufSize = bytesPerLine; /* read full buffer */ + } else { + bufSize = (uint8_t)(endAddr-addr+1); + } + if (readfp(hndl, addr, buf, bufSize)!=ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Read failed!\r\n", io->stdErr); + return ERR_FAILED; + } + if (res != ERR_OK) { + CLS1_SendStr((unsigned char*)"\r\n*** Failure reading memory block!\r\n", io->stdErr); + return ERR_FAULT; + } + /* write address */ + UTIL1_strcpy(str, sizeof(str), (unsigned char*)"0x"); + UTIL1_strcatNumHex(str, sizeof(str), addr, addrSize); + UTIL1_chcat(str, sizeof(str), ':'); + CLS1_SendStr((unsigned char*)str, io->stdOut); + /* write data in hex */ + str[0] = '\0'; + for (j=0; jstdOut); + /* write in ASCII */ + io->stdOut(' '); + for (j=0; j= ' ' && ch <= 0x7f) { + io->stdOut(ch); + } else { + io->stdOut('.'); /* place holder */ + } + } + for (/*empty*/; jstdOut); + addr += bytesPerLine; + } + return ERR_OK; +} + +/* END CLS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.h new file mode 100644 index 0000000..33fc681 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1.h @@ -0,0 +1,830 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CLS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Shell +** Version : Component 01.108, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:38, # CodeGen: 15 +** Abstract : +** Module implementing a command line shell. +** Settings : +** Component name : CLS1 +** Echo : no +** Prompt : "CMD>" +** Project Name : TinyK20 OpenPnP Feeder +** Silent Mode Prefix : # +** Buffer Size : 48 +** Blocking Send : Enabled +** Wait : WAIT1 +** Timeout (ms) : 20 +** Wait Time (ms) : 5 +** RTOS Wait : yes +** Status Colon Pos : 13 +** Help Semicolon Pos : 26 +** Multi Command : Disabled +** Utility : UTIL1 +** Default Serial : Enabled +** Console Interface : AS1 +** Semaphore : no +** Critical Section : CS1 +** History : no +** Kinetis SDK : MCUC1 +** Contents : +** PrintPrompt - void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +** SendNum8u - void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum8s - void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16u - void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum16s - void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32u - void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +** SendNum32s - void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +** SendCh - void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +** SendStr - void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +** PrintMemory - uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr,... +** printfIO - unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +** printf - unsigned CLS1_printf(const char *fmt, ...); +** SendData - void CLS1_SendData(const uint8_t *data, uint16_t dataSize,... +** PrintStatus - uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +** ParseCommand - uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled,... +** IsHistoryCharacter - bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx,... +** ReadLine - bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize,... +** PrintCommandFailed - void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +** IterateTable - uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled,... +** SetStdio - uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +** GetStdio - CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +** RequestSerial - void CLS1_RequestSerial(void); +** ReleaseSerial - void CLS1_ReleaseSerial(void); +** ReadAndParseWithCommandTableExt - uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t... +** ReadAndParseWithCommandTable - uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize,... +** ParseWithCommandTableExt - uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType... +** ParseWithCommandTable - uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType... +** GetSemaphore - void* CLS1_GetSemaphore(void); +** SendStatusStr - void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus,... +** SendHelpStr - void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp,... +** ReadChar - void CLS1_ReadChar(uint8_t *c); +** SendChar - void CLS1_SendChar(uint8_t ch); +** KeyPressed - bool CLS1_KeyPressed(void); +** SendCharFct - void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +** Init - void CLS1_Init(void); +** Deinit - void CLS1_Deinit(void); +** +** * Copyright (c) 2014-2020, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CLS1.h +** @version 01.00 +** @brief +** Module implementing a command line shell. +*/ +/*! +** @addtogroup CLS1_module CLS1 module documentation +** @{ +*/ + + +#ifndef __CLS1_H +#define __CLS1_H + +/* MODULE CLS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CLS1config.h" /* configuration */ + + +#ifndef __BWUserType_CLS1_StdIO_OutErr_FctType +#define __BWUserType_CLS1_StdIO_OutErr_FctType + typedef void (*CLS1_StdIO_OutErr_FctType)(uint8_t); /* Callback for an output or error I/O function */ +#endif +#ifndef __BWUserType_CLS1_StdIO_In_FctType +#define __BWUserType_CLS1_StdIO_In_FctType + typedef void (*CLS1_StdIO_In_FctType)(uint8_t *); /* Callback for an I/O input function. */ +#endif +#ifndef __BWUserType_CLS1_StdIO_KeyPressed_FctType +#define __BWUserType_CLS1_StdIO_KeyPressed_FctType + typedef bool (*CLS1_StdIO_KeyPressed_FctType)(void); /* Callback which returns true if a key has been pressed */ +#endif +#ifndef __BWUserType_CLS1_StdIOType +#define __BWUserType_CLS1_StdIOType + typedef struct { /* Record containing input, output and error callback (stdin, stdout, stderr). */ + CLS1_StdIO_In_FctType stdIn; /* standard input */ + CLS1_StdIO_OutErr_FctType stdOut; /* standard output */ + CLS1_StdIO_OutErr_FctType stdErr; /* standard error */ + CLS1_StdIO_KeyPressed_FctType keyPressed; /* key pressed callback */ + } CLS1_StdIOType; +#endif +#ifndef __BWUserType_CLS1_ConstStdIOType +#define __BWUserType_CLS1_ConstStdIOType + typedef const CLS1_StdIOType CLS1_ConstStdIOType; /* constant StdIOType */ +#endif +#ifndef __BWUserType_CLS1_ParseCommandCallback +#define __BWUserType_CLS1_ParseCommandCallback + typedef uint8_t (*CLS1_ParseCommandCallback)(const uint8_t *cmd, bool *handled, const CLS1_StdIOType *io); /* Callback for parsing a shell command */ +#endif +#ifndef __BWUserType_CLS1_ConstStdIOTypePtr +#define __BWUserType_CLS1_ConstStdIOTypePtr + typedef const CLS1_ConstStdIOType *CLS1_ConstStdIOTypePtr; /* Pointer to constant standard I/O descriptor */ +#endif +#ifndef __BWUserType_CLS1_ConstParseCommandCallback +#define __BWUserType_CLS1_ConstParseCommandCallback + typedef const CLS1_ParseCommandCallback CLS1_ConstParseCommandCallback; /* Callback for parsing a shell command */ +#endif + +#define CLS1_DEFAULT_SHELL_BUFFER_SIZE CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE /* default buffer size for shell command parsing */ + +/* Include inherited components */ + +/* other includes needed */ +#include /* for size_t */ + +/* settings for command line history */ +#define CLS1_HISTORY_ENABLED 0 /* 1: enabled, 0: disabled */ +#define CLS1_NOF_HISTORY 0 /* number of items in history */ +#define CLS1_HIST_LEN 0 /* history buffer size */ + +/* settings for silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR '#' /* with this char as first character in the cmd, printing is silent. Use a space to disable it */ +#define CLS1_NO_SILENT_PREFIX_CHAR ' ' /* used for no silent prefix char */ +#define CLS1_SILENT_PREFIX_CHAR_ENABLED (CLS1_SILENT_PREFIX_CHAR != CLS1_NO_SILENT_PREFIX_CHAR) + +/* settings for local echo */ +#define CLS1_ECHO_ENABLED 0 /* 1: enabled, 0: disabled */ + +#define CLS1_DEFAULT_SERIAL CLS1_CONFIG_DEFAULT_SERIAL /* If set to 1, then the shell implements its own StdIO which is returned by CLS1_GetStdio(); */ + +extern uint8_t CLS1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +#if CLS1_DEFAULT_SERIAL + extern CLS1_ConstStdIOType CLS1_stdio; /* default standard I/O */ +#endif + +#define CLS1_DASH_LINE "--------------------------------------------------------------" +/* predefined commands */ +#define CLS1_CMD_HELP "help" +#define CLS1_CMD_STATUS "status" + +#ifdef __cplusplus +extern "C" { +#endif + +void CLS1_SendStr(const uint8_t *str, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStr (component Shell) +** +** Description : +** Prints a string using an I/O function +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string (zero terminated) to be +** printed. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseCommand(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component Shell) +** +** Description : +** Parses a shell command. Use 'help' to get a list of +** supported commands. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to variable to indicate if +** the command has been handled. The caller +** passes this variable to the command scanner +** to find out if the passed command has been +** handled. The variable is initialized by the +** caller. +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendNum32s(int32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32s (component Shell) +** +** Description : +** Sends a 32bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16s(int16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16s (component Shell) +** +** Description : +** Sends a 16bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_PrintPrompt(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintPrompt (component Shell) +** +** Description : +** Prints the prompt to the stdOut channel +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to IO to be used +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_ReadLine(uint8_t *bufStart, uint8_t *buf, size_t bufSize, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : ReadLine (component Shell) +** +** Description : +** Reads a line from stdIn and returns TRUE if we have a line, +** FALSE otherwise. +** Parameters : +** NAME - DESCRIPTION +** * bufStart - Pointer to start of buffer +** * buf - Pointer to buffer where to read in the +** information +** bufSize - size of buffer +** * io - Pointer to I/O callbacks +** Returns : +** --- - TRUE if something has been read, FALSE +** otherwise +** =================================================================== +*/ + +uint8_t CLS1_PrintStatus(CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintStatus (component Shell) +** +** Description : +** Prints various available system status information +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to I/O callbacks +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_PrintCommandFailed(const uint8_t *cmd, CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintCommandFailed (component Shell) +** +** Description : +** Prints a standard message for failed or unknown commands +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command which was failing +** * io - Pointer to I/O callbacks +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTable(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ParseWithCommandTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr CLS1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component Shell) +** +** Description : +** Returns the default stdio channel. This method is only +** available if a shell is enabled in the component properties. +** Parameters : None +** Returns : +** --- - Pointer to the stdio descriptor +** =================================================================== +*/ + +void CLS1_SendNum32u(uint32_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum32u (component Shell) +** +** Description : +** Sends a 32bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum16u(uint16_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum16u (component Shell) +** +** Description : +** Sends a 16bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8u(uint8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8u (component Shell) +** +** Description : +** Sends an 8bit unsigned number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendNum8s(int8_t val, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendNum8s (component Shell) +** +** Description : +** Sends an 8bit signed number to the given I/O +** Parameters : +** NAME - DESCRIPTION +** val - number to print +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_Init(void); +/* +** =================================================================== +** Method : Init (component Shell) +** +** Description : +** Initializes the module, especially creates the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_RequestSerial(void); +/* +** =================================================================== +** Method : RequestSerial (component Shell) +** +** Description : +** Used to get mutual access to the shell console. Only has an +** effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReleaseSerial(void); +/* +** =================================================================== +** Method : ReleaseSerial (component Shell) +** +** Description : +** Used to release mutual access to the shell console. Only has +** an effect if using an RTOS with semaphore for the console +** access. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendHelpStr(const uint8_t *strCmd, const uint8_t *strHelp, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendHelpStr (component Shell) +** +** Description : +** Prints a string using an I/O function, formated for the +** 'help' command +** Parameters : +** NAME - DESCRIPTION +** * strCmd - Pointer to string of the command +** * strHelp - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendStatusStr(const uint8_t *strItem, const uint8_t *strStatus, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendStatusStr (component Shell) +** +** Description : +** Prints a status string using an I/O function, formated for +** the 'status' command +** Parameters : +** NAME - DESCRIPTION +** * strItem - Pointer to string of the command +** * strStatus - Pointer to help text string +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_ReadChar(uint8_t *c); +/* +** =================================================================== +** Method : ReadChar (component Shell) +** +** Description : +** Reads a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to character to be used to store the +** result +** Returns : Nothing +** =================================================================== +*/ + +void CLS1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component Shell) +** +** Description : +** Sends a character (blocking) +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_KeyPressed(void); +/* +** =================================================================== +** Method : KeyPressed (component Shell) +** +** Description : +** Checks if a key has been pressed (a character is present in +** the input buffer) +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Shell) +** +** Description : +** De-Initializes the module, especially frees the mutex +** semaphore if an RTOS is used. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void* CLS1_GetSemaphore(void); +/* +** =================================================================== +** Method : GetSemaphore (component Shell) +** +** Description : +** Return the semaphore of the shell. +** Parameters : None +** Returns : +** --- - semaphore, or NULL if not used or not +** allocated. +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTable(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTable (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_IterateTable(const uint8_t *cmd, bool *handled, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parserTable); +/* +** =================================================================== +** Method : IterateTable (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * handled - Pointer to boolean which is set to +** TRUE if a command parser has handled the +** command. +** * io - Pointer to I/O callbacks +** * parserTable - Pointer to callback which +** will be called to parse commands in the +** user application, or NULL if not used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_SetStdio(CLS1_ConstStdIOTypePtr stdio); +/* +** =================================================================== +** Method : SetStdio (component Shell) +** +** Description : +** Sets an StdIO structure which is returned by GetStdio() +** Parameters : +** NAME - DESCRIPTION +** stdio - New stdio structure to be used. +** Returns : +** --- - Error code +** =================================================================== +*/ + +void CLS1_SendData(const uint8_t *data, uint16_t dataSize, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendData (component Shell) +** +** Description : +** Sends data using an I/O function. Unlike SendStr(), with +** this method it is possible to send binary data, including +** zero bytes. +** Parameters : +** NAME - DESCRIPTION +** * data - Pointer to data to be sent +** dataSize - Number of bytes to be sent. +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +bool CLS1_IsHistoryCharacter(uint8_t ch, uint8_t *cmdBuf, size_t cmdBufIdx, bool *isPrev); +/* +** =================================================================== +** Method : IsHistoryCharacter (component Shell) +** +** Description : +** Returns TRUE if character is a history character +** Parameters : +** NAME - DESCRIPTION +** ch - current command character +** * cmdBuf - Pointer to command line buffer read +** so far +** cmdBufIdx - Index of character into cmdBuf +** * isPrev - Pointer to return value, if it is +** 'previous' history or not +** Returns : +** --- - TRUE if it is an accepted history character +** =================================================================== +*/ + +void CLS1_SendCh(uint8_t ch, CLS1_StdIO_OutErr_FctType io); +/* +** =================================================================== +** Method : SendCh (component Shell) +** +** Description : +** Prints a character using an I/O function +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** io - I/O callbacks to be used for printing. +** Returns : Nothing +** =================================================================== +*/ + +unsigned CLS1_printf(const char *fmt, ...); +/* +** =================================================================== +** Method : printf (component Shell) +** +** Description : +** Printf() style function using XFormat component, using the +** shell default I/O handler. +** Parameters : +** NAME - DESCRIPTION +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_printfPutChar(void *arg, char c); +/* +** =================================================================== +** Method : CLS1_printfPutChar (component Shell) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +unsigned CLS1_printfIO(CLS1_ConstStdIOType *io, const char *fmt, ...); +/* +** =================================================================== +** Method : printfIO (component Shell) +** +** Description : +** Printf() style function using XFormat component, using a +** custom I/O handler. +** Parameters : +** NAME - DESCRIPTION +** * io - Pointer to +** fmt - printf style format string +** Returns : +** --- - number of characters written +** =================================================================== +*/ + +void CLS1_SendCharFct(uint8_t ch, uint8_t (*fct)(uint8_t ch)); +/* +** =================================================================== +** Method : SendCharFct (component Shell) +** +** Description : +** Method to send a character using a standard I/O handle. +** Parameters : +** NAME - DESCRIPTION +** ch - character to be sent +** * fct - Function pointer to output function: takes +** a byte to write and returns error code. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t CLS1_PrintMemory(void *hndl, uint32_t startAddr, uint32_t endAddr, uint8_t addrSize, uint8_t bytesPerLine, uint8_t (*readfp)(void *, uint32_t, uint8_t*, size_t), CLS1_ConstStdIOType *io); +/* +** =================================================================== +** Method : PrintMemory (component Shell) +** +** Description : +** Prints a chunk of memory bytes in a formatted way. +** Parameters : +** NAME - DESCRIPTION +** * hndl - Pointer to +** startAddr - Memory start address +** endAddr - Memory end address +** addrSize - Number of bytes for the address +** (1, 2, 3 or 4) +** bytesPerLine - Number of bytes per line +** readfp - Function pointer to read the memory. +** Returns error code, uses a device handle, +** 32bit address with a pointer to a buffer +** and a buffer size. +** * io - Pointer to I/O to be used +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ReadAndParseWithCommandTableExt(uint8_t *cmdBuf, size_t cmdBufSize, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ReadAndParseWithCommandTableExt (component Shell) +** +** Description : +** Reads characters from the default input channel and appends +** it to the buffer. Once a new line has been detected, the +** line will be parsed using the handlers in the table. +** Parameters : +** NAME - DESCRIPTION +** * cmdBuf - Pointer to buffer provided by the +** caller where to store the command to read +** in. Characters will be appended, so make +** sure string buffer is initialized with a +** zero byte at the beginning. +** cmdBufSize - Size of buffer +** * io - Pointer to I/O channels to be used +** * parseCallback - Pointer to callback +** table provided by the user application to +** parse commands. The table has a NULL +** sentinel. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t CLS1_ParseWithCommandTableExt(const uint8_t *cmd, CLS1_ConstStdIOType *io, CLS1_ConstParseCommandCallback *parseCallback, bool silent); +/* +** =================================================================== +** Method : ParseWithCommandTableExt (component Shell) +** +** Description : +** Parses a shell command. It handles first the internal +** commands and will call the provided callback. +** Parameters : +** NAME - DESCRIPTION +** * cmd - Pointer to command string +** * io - Pointer to I/O callbacks +** * parseCallback - Pointer to callback +** which will be called to parse commands in +** the user application, or NULL if not used. +** silent - If handling shall be silent, i.e. no +** command prompt printed +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END CLS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __CLS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1config.h new file mode 100644 index 0000000..ece252b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CLS1config.h @@ -0,0 +1,82 @@ +#ifndef __CLS1_CONFIG_H +#define __CLS1_CONFIG_H + +#ifndef CLS1_CONFIG_BLOCKING_SEND_ENABLED + #define CLS1_CONFIG_BLOCKING_SEND_ENABLED (1) + /*!< 1: Sending is blocking (with an optional timeout); 0: Do not block on sending */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (20) + /*!< Total blocking time (timeout) in milliseconds, uses 0 for blocking without a timeout */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS + #define CLS1_CONFIG_BLOCKING_SEND_TIMEOUT_WAIT_MS (5) + /*!< waiting time during blocking, use 0 (zero) for polling */ +#endif + +#ifndef CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT + #define CLS1_CONFIG_BLOCKING_SEND_RTOS_WAIT (1) + /*!< 1: Use WaitmsOS() instead of Waitms(); 0: Use Waitms() instead of WaitOSms() */ +#endif + +#ifndef CLS1_CONFIG_USE_MUTEX + #define CLS1_CONFIG_USE_MUTEX (0) + /*!< 1: use RTOS mutex; 0: do not use RTOS mutex */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE + #define CLS1_CONFIG_DEFAULT_SHELL_BUFFER_SIZE (48) + /*!< default buffer size for shell command parsing */ +#endif + +#ifndef CLS1_CONFIG_DEFAULT_SERIAL + #define CLS1_CONFIG_DEFAULT_SERIAL (1) + /*!< 1: the shell implements its own StdIO which is returned by GetStdio(); 0: The shell does not implement its own standard I/O */ +#endif + +#if CLS1_CONFIG_DEFAULT_SERIAL + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE + #define CLS1_CONFIG_DEFAULT_SERIAL_INCLUDE "AS1.h" + /*!< Include for the functions below */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RECEIVE_FCT_NAME AS1_RecvChar + /*!< Function name to read a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_SEND_FCT_NAME AS1_SendChar + /*!< Function name to send a character and returning ERR_OK if it was successful */ + #endif + + #ifndef CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME + #define CLS1_CONFIG_DEFAULT_SERIAL_RXAVAIL_FCT_NAME AS1_GetCharsInRxBuf + /*!< Function name to check if there is anything available to receive and returns TRUE, otherwise FALSE */ + #endif +#endif + +#ifndef CLS1_CONFIG_PROMPT_STRING + #define CLS1_CONFIG_PROMPT_STRING "CMD>" +#endif + +#ifndef CLS1_CONFIG_PROJECT_NAME_STRING + #define CLS1_CONFIG_PROJECT_NAME_STRING "TinyK20 OpenPnP Feeder" +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_ENABLED + #define CLS1_CONFIG_MULTI_CMD_ENABLED (0) /* 1: enabled, 0: disabled */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_SIZE + #define CLS1_CONFIG_MULTI_CMD_SIZE (32) /* max size of each command */ +#endif + +#ifndef CLS1_CONFIG_MULTI_CMD_CHAR + #define CLS1_CONFIG_MULTI_CMD_CHAR ';' /* separation character */ +#endif + + +#endif /* __CLS1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.c new file mode 100644 index 0000000..a21b34f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.c @@ -0,0 +1,151 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +/* MODULE CS1. */ + +#include "CS1.h" + +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_CriticalVariable(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_EnterCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void CS1_ExitCritical(void) +{ + *** Implemented as macro in the header file CS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void CS1_Init(void) +{ + /* nothing needed */ +} + +/* END CS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.h new file mode 100644 index 0000000..6b56a87 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1.h @@ -0,0 +1,216 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : CS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : CriticalSection +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : CS1 +** SDK : MCUC1 +** Use Processor Expert Default : no +** Use FreeRTOS : no +** Contents : +** CriticalVariable - void CS1_CriticalVariable(void); +** EnterCritical - void CS1_EnterCritical(void); +** ExitCritical - void CS1_ExitCritical(void); +** Deinit - void CS1_Deinit(void); +** Init - void CS1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file CS1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup CS1_module CS1 module documentation +** @{ +*/ + +#ifndef __CS1_H +#define __CS1_H + +/* MODULE CS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "CS1config.h" /* configuration */ + + +/* other includes needed */ +#if CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #include "FreeRTOS.h" + #include "task.h" /* FreeRTOS header file for taskENTER_CRITICAL() and taskEXIT_CRITICAL() macros */ +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +/* workaround macros for wrong EnterCritical()/ExitCritical() in the low level drivers. */ +#define CS1_CriticalVariableDrv() \ + CS1_CriticalVariable() +#define CS1_EnterCriticalDrv() \ + CS1_EnterCritical() +#define CS1_ExitCriticalDrv() \ + CS1_ExitCritical() + +#ifdef __HIWARE__ + #pragma MESSAGE DISABLE C3303 /* C3303 Implicit concatenation of strings */ +#endif + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CriticalVariable() /* nothing needed */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_CriticalVariable() /* nothing needed */ + #else + #define CS1_CriticalVariable() uint8_t cpuSR; /* variable to store current status */ + #endif +#endif +/* +** =================================================================== +** Method : CriticalVariable (component CriticalSection) +** +** Description : +** Defines a variable if necessary. This is a macro. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_EnterCritical() EnterCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_EnterCritical() taskENTER_CRITICAL_FROM_ISR() /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_EnterCritical() \ + do { \ + __asm volatile( "csrc mstatus, 8" ); /* Disable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_EnterCritical() \ + do { \ + /*lint -save -esym(529,cpuSR) Symbol 'cpuSR' not subsequently referenced. */\ + __asm ( \ + "mrs r0, PRIMASK \n\t" \ + "cpsid i \n\t" \ + "strb r0, %[output] \n\t" \ + : [output] "=m" (cpuSR) :: "r0"); \ + __asm ("" ::: "memory"); \ + /*lint -restore Symbol 'cpuSR' not subsequently referenced. */\ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : EnterCritical (component CriticalSection) +** +** Description : +** Enters a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_ExitCritical() ExitCritical() +#elif CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_ExitCritical() taskEXIT_CRITICAL_FROM_ISR(0) /* FreeRTOS critical section inside interrupt */ +#elif CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + + #if MCUC1_CONFIG_CPU_IS_RISC_V + #define CS1_ExitCritical() \ + do { \ + __asm volatile( "csrs mstatus, 8" ); /* Enable interrupts \todo */ \ + } while(0) + #elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define CS1_ExitCritical() \ + do{ \ + __asm ( \ + "ldrb r0, %[input] \n\t" \ + "msr PRIMASK,r0 \n\t" \ + ::[input] "m" (cpuSR) : "r0"); \ + } while(0) + #endif +#endif +/* +** =================================================================== +** Method : ExitCritical (component CriticalSection) +** +** Description : +** Exits a critical section +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component CriticalSection) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void CS1_Init(void); +/* +** =================================================================== +** Method : Init (component CriticalSection) +** +** Description : +** driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END CS1. */ + +#ifdef __cplusplus +} +#endif + +#endif +/* ifndef __CS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1config.h new file mode 100644 index 0000000..2fe3b70 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/CS1config.h @@ -0,0 +1,18 @@ +#ifndef __CS1_CONFIG_H +#define __CS1_CONFIG_H + +/* select ONE of the following implementation methods: */ +#ifndef CS1_CONFIG_USE_RTOS_CRITICAL_SECTION + #define CS1_CONFIG_USE_RTOS_CRITICAL_SECTION 0 /* 1: use FreeRTOS critical section; 0: don't use FreeRTOS critical sections */ +#endif + +#ifndef CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION + #define CS1_CONFIG_USE_CUSTOM_CRITICAL_SECTION 1 /* 1: Custom implementation (supported for GNU and ARM!); 0: don't use custom implementation */ +#endif + +#ifndef CS1_CONFIG_USE_PEX_DEFAULT + #define CS1_CONFIG_USE_PEX_DEFAULT 0 /* 1: use Processor Expert default; 0: use alternative implementation */ +#endif + +#endif /* __CS1_CONFIG_H */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.c new file mode 100644 index 0000000..2bd7219 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.c @@ -0,0 +1,1270 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : MK20DX128FT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K20P48M50SF0RM Rev. 1, Oct 2011 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : Cpu +** CPU type : MK20DN128VFT5 +** CPU : CPU +** MemModelDev : MemModel_NoFlexMem +** Clock settings : +** Internal oscillator : +** Slow internal reference clock [kHz] : 32.768 +** Initialize slow trim value : no +** Fast internal reference clock [MHz] : 4 +** Initialize fast trim value : no +** RTC oscillator : Disabled +** System oscillator 0 : Enabled +** Clock source : External crystal +** Clock input pin : +** Pin name : EXTAL0/PTA18/FTM0_FLT2/FTM_CLKIN0 +** Pin signal : EXTAL +** Clock output pin : +** Pin name : XTAL0/PTA19/FTM1_FLT0/FTM_CLKIN1/LPTMR0_ALT1 +** Pin signal : XTAL +** Clock frequency [MHz] : 8 +** Capacitor load : 0pF +** Oscillator operating mode : Low power +** Clock source settings : 1 +** Clock source setting 0 : +** Internal reference clock : +** MCGIRCLK clock : Enabled +** MCGIRCLK in stop : Disabled +** MCGIRCLK source : Slow +** MCGIRCLK clock [MHz] : 0.032768 +** External reference clock : +** OSC0ERCLK clock : Enabled +** OSC0ERCLK in stop : Disabled +** OSC0ERCLK clock [MHz] : 8 +** ERCLK32K clock source : Auto select +** ERCLK32K. clock [kHz] : 0.001 +** MCG settings : +** MCG mode : PEE +** MCG output clock : PLL clock +** MCG output [MHz] : 100 +** MCG external ref. clock source : System oscillator 0 +** MCG external ref. clock [MHz] : 8 +** Clock monitor : Disabled +** FLL settings : +** FLL module : Disabled +** FLL output [MHz] : 0 +** MCGFFCLK clock [kHz] : 31.25 +** Reference clock source : External clock +** Reference clock divider : Auto select +** FLL reference clock [kHz] : 31.25 +** Multiplication factor : Auto select +** PLL 0 settings : +** PLL module : Enabled +** PLL module in Stop : Disabled +** PLL output [MHz] : 100 +** Reference clock divider : Auto select +** PLL reference clock [MHz] : 4 +** Multiplication factor : Auto select +** Loss of lock interrupt : Disabled +** Initialization priority : minimal priority +** Watchdog disable : yes +** Internal peripherals : +** NMI pin : Enabled +** NMI Pin : TSI0_CH5/PTA4/LLWU_P3/FTM0_CH1/NMI_b/EZP_CS_b +** NMI Pin signal : +** Reset control : Enabled +** Reset pin : RESET_b +** Reset pin signal : +** Filter in STOP : Disabled +** Filter in RUN/WAIT : Disabled +** Filter width : 1 +** Debug interface (JTAG) : +** JTAG Mode : JTAG +** TDI : Disabled +** TDO : Disabled +** TCK : Enabled +** TCK Pin : TSI0_CH1/PTA0/UART0_CTS_b/UART0_COL_b/FTM0_CH5/JTAG_TCLK/SWD_CLK/EZP_CLK +** TCK Pin signal : +** TMS : Enabled +** TMS Pin : TSI0_CH4/PTA3/UART0_RTS_b/FTM0_CH0/JTAG_TMS/SWD_DIO +** TMS Pin signal : +** nTRST : Disabled +** Flash memory organization : +** Flash blocks : 1 +** Flash block 0 : PFlash +** Address : 0x0 +** Size : 131072 +** Write unit size : 4 +** Erase unit size : 1024 +** Protection unit size : 4096 +** Flexible memory controller : Disabled +** Flash configuration field : Disabled +** System control block settings : Disabled +** Power management controller : +** LVD reset : Enabled +** LVD voltage treshold : Low +** LVW voltage treshold : Low +** Bandgap buffer : Disabled +** LVD interrupt : +** Interrupt : INT_LVD_LVW +** Interrupt request : Disabled +** Interrupt priority : 0 (Highest) +** LVD interrupt : Disabled +** LVW interrupt : Disabled +** System Integration Module : +** CLKOUT pin control : Disabled +** Clock gating control : Disabled +** CPU interrupts/resets : +** NMI interrupt : Enabled +** Interrupt : INT_NMI +** Hard Fault : Disabled +** Bus Fault : Disabled +** Usage Fault : Disabled +** Supervisor Call : Disabled +** Pendable Service : Disabled +** MCG : Disabled +** Low power mode settings : +** Allowed power modes : +** Very low power modes : Not allowed +** Low leakage stop mode : Not allowed +** Very low leakage stop mode : Not allowed +** LLWU settings : Disabled +** Operation mode settings : +** WAIT operation mode : +** Return to wait after ISR : no +** SLEEP operation mode : +** Return to stop after ISR : no +** STOP operation mode : Disabled +** Clock configurations : 1 +** Clock configuration 0 : +** __IRC_32kHz : 0.032768 +** __IRC_4MHz : 2 +** __SYSTEM_OSC : 8 +** __RTC_OSC : 0 +** Very low power mode : Disabled +** Clock source setting : configuration 0 +** MCG mode : PEE +** MCG output [MHz] : 100 +** MCGIRCLK clock [MHz] : 0.032768 +** OSCERCLK clock [MHz] : 8 +** ERCLK32K. clock [kHz] : 0.001 +** MCGFFCLK [kHz] : 31.25 +** System clocks : +** Core clock prescaler : Auto select +** Core clock : 50 +** Bus clock prescaler : Auto select +** Bus clock : 25 +** Flash clock prescaler : Auto select +** Flash clock : 25 +** PLL/FLL clock selection : PLL clock +** Clock frequency [MHz] : 100 +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +/* MODULE Cpu. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "MCUC1.h" +#include "SW_FWD.h" +#include "BitIoLdd2.h" +#include "SW_REV.h" +#include "BitIoLdd3.h" +#include "SW_PEELER.h" +#include "BitIoLdd4.h" +#include "ENC1.h" +#include "BitIoLdd5.h" +#include "PWMA.h" +#include "PwmLdd1.h" +#include "TU1.h" +#include "DIRA.h" +#include "BitIoLdd6.h" +#include "DIRB.h" +#include "BitIoLdd7.h" +#include "PWMB.h" +#include "PwmLdd2.h" +#include "HMODE.h" +#include "BitIoLdd8.h" +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "WAIT1.h" +#include "CLS1.h" +#include "XF1.h" +#include "CS1.h" +#include "LED2.h" +#include "LEDpin2.h" +#include "BitIoLdd9.h" +#include "AS1.h" +#include "ASerialLdd1.h" +#include "HF1.h" +#include "TU2.h" +#include "KIN1.h" +#include "RTT1.h" +#include "AS2.h" +#include "ASerialLdd2.h" +#include "UTIL1.h" +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +#include "Events.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Global variables */ +volatile uint8_t SR_reg; /* Current value of the FAULTMASK register */ +volatile uint8_t SR_lock = 0x00U; /* Lock */ + +/* +** =================================================================== +** Method : Cpu_SetBASEPRI (component MK20DX128FT5) +** +** Description : +** This method sets the BASEPRI core register. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void Cpu_SetBASEPRI(uint32_t Level); + +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK20DX128FT5) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_INT_NMIInterrupt) +{ + Cpu_OnNMIINT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Mem_Manage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Mem_Manage_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Bus_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Bus_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Usage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Usage_Fault) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved7 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved7) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved8 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved8) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved9 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved9) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved10 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved10) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DebugMonitor (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DebugMonitor) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved13 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved13) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA2) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA3) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA_Error (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_DMA_Error) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved21 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Reserved21) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTFL (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_FTFL) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Read_Collision (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Read_Collision) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LVD_LVW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LVD_LVW) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LLW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LLW) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Watchdog (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_Watchdog) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2C0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2C0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SPI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_SPI0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Tx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2S0_Tx) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Rx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_I2S0_Rx) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_LON (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART0_LON) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART1_RX_TX) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_UART1_ERR) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_ADC0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_ADC0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMP0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMP1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_FTM0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_FTM1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMT (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_CMT) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_RTC) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC_Seconds (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_RTC_Seconds) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT1) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT2) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PIT3) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PDB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PDB0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_USB0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USBDCD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_USBDCD) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_TSI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_TSI0) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_MCG (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_MCG) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LPTimer (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_LPTimer) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTA (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTA) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTB (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTB) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTC) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTD) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTE (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_PORTE) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SWI (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(Cpu_ivINT_SWI) +{ + /* This code can be changed using the CPU component property "Build Options / Unhandled int code" */ + PE_DEBUGHALT(); +} + + +/*** !!! Here you can place your own code using property "User data declarations" on the build options tab. !!! ***/ + +/*lint -esym(765,__init_hardware) Disable MISRA rule (8.10) checking for symbols (__init_hardware). The function is linked to the EWL library */ +/*lint -esym(765,Cpu_Interrupt) Disable MISRA rule (8.10) checking for symbols (Cpu_Interrupt). */ +void __init_hardware(void) +{ + + /*** !!! Here you can place your own code before PE initialization using property "User code before PE initialization" on the build options tab. !!! ***/ + + /*** ### MK20DN128VFT5 "Cpu" init code ... ***/ + /*** PE initialization code after reset ***/ + SCB_VTOR = (uint32_t)(&__vect_table); /* Set the interrupt vector table position */ + /* Disable the WDOG module */ + /* WDOG_UNLOCK: WDOGUNLOCK=0xC520 */ + WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */ + /* WDOG_UNLOCK: WDOGUNLOCK=0xD928 */ + WDOG_UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */ + /* WDOG_STCTRLH: ??=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,??=0,??=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */ + WDOG_STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) | + WDOG_STCTRLH_WAITEN_MASK | + WDOG_STCTRLH_STOPEN_MASK | + WDOG_STCTRLH_ALLOWUPDATE_MASK | + WDOG_STCTRLH_CLKSRC_MASK | + 0x0100U; + + /* System clock initialization */ + /* SIM_CLKDIV1: OUTDIV1=0,OUTDIV2=1,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x00) | + SIM_CLKDIV1_OUTDIV2(0x01) | + SIM_CLKDIV1_OUTDIV4(0x03); /* Set the system prescalers to safe value */ + /* SIM_SCGC5: PORTD=1,PORTC=1,PORTB=1,PORTA=1 */ + SIM_SCGC5 |= SIM_SCGC5_PORTD_MASK | + SIM_SCGC5_PORTC_MASK | + SIM_SCGC5_PORTB_MASK | + SIM_SCGC5_PORTA_MASK; /* Enable clock gate for ports to enable pin routing */ + if ((PMC_REGSC & PMC_REGSC_ACKISO_MASK) != 0x0U) { + /* PMC_REGSC: ACKISO=1 */ + PMC_REGSC |= PMC_REGSC_ACKISO_MASK; /* Release IO pads after wakeup from VLLS mode. */ + } + /* SIM_CLKDIV1: OUTDIV1=1,OUTDIV2=3,??=0,??=0,??=0,??=0,OUTDIV4=3,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0 */ + SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0x01) | + SIM_CLKDIV1_OUTDIV2(0x03) | + SIM_CLKDIV1_OUTDIV4(0x03); /* Update system prescalers */ + /* SIM_SOPT2: PLLFLLSEL=1 */ + SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; /* Select PLL as a clock source for various peripherals */ + /* SIM_SOPT1: OSC32KSEL=3 */ + SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(0x03); /* LPO 1kHz oscillator drives 32 kHz clock for various peripherals */ + /* PORTA_PCR18: ISF=0,MUX=0 */ + PORTA_PCR18 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); + /* PORTA_PCR19: ISF=0,MUX=0 */ + PORTA_PCR19 &= (uint32_t)~(uint32_t)((PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x07))); + /* Switch to FBE Mode */ + /* MCG_C2: LOCRE0=0,??=0,RANGE0=2,HGO0=0,EREFS0=1,LP=0,IRCS=0 */ + MCG_C2 = (MCG_C2_RANGE0(0x02) | MCG_C2_EREFS0_MASK); + /* OSC0_CR: ERCLKEN=1,??=0,EREFSTEN=0,??=0,SC2P=0,SC4P=0,SC8P=0,SC16P=0 */ + OSC0_CR = OSC_CR_ERCLKEN_MASK; + /* MCG_C7: OSCSEL=0 */ + MCG_C7 &= (uint8_t)~(uint8_t)(MCG_C7_OSCSEL_MASK); + /* MCG_C1: CLKS=2,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG_C1 = (MCG_C1_CLKS(0x02) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); + /* MCG_C4: DMX32=0,DRST_DRS=0 */ + MCG_C4 &= (uint8_t)~(uint8_t)((MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0x03))); + /* MCG_C5: ??=0,PLLCLKEN0=0,PLLSTEN0=0,PRDIV0=1 */ + MCG_C5 = MCG_C5_PRDIV0(0x01); + /* MCG_C6: LOLIE0=0,PLLS=0,CME0=0,VDIV0=1 */ + MCG_C6 = MCG_C6_VDIV0(0x01); + while((MCG_S & MCG_S_OSCINIT0_MASK) == 0x00U) { /* Check that the oscillator is running */ + } + while((MCG_S & MCG_S_IREFST_MASK) != 0x00U) { /* Check that the source of the FLL reference clock is the external reference clock. */ + } + while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + /* Switch to PBE Mode */ + /* MCG_C6: LOLIE0=0,PLLS=1,CME0=0,VDIV0=1 */ + MCG_C6 = (MCG_C6_PLLS_MASK | MCG_C6_VDIV0(0x01)); + while((MCG_S & 0x0CU) != 0x08U) { /* Wait until external reference clock is selected as MCG output */ + } + while((MCG_S & MCG_S_LOCK0_MASK) == 0x00U) { /* Wait until locked */ + } + /* Switch to PEE Mode */ + /* MCG_C1: CLKS=0,FRDIV=3,IREFS=0,IRCLKEN=1,IREFSTEN=0 */ + MCG_C1 = (MCG_C1_CLKS(0x00) | MCG_C1_FRDIV(0x03) | MCG_C1_IRCLKEN_MASK); + while((MCG_S & 0x0CU) != 0x0CU) { /* Wait until output of the PLL is selected */ + } + /*** End of PE initialization code after reset ***/ + + /*** !!! Here you can place your own code after PE initialization using property "User code after PE initialization" on the build options tab. !!! ***/ + +} + +/* +** =================================================================== +** Method : Cpu_SetBASEPRI (component MK20DX128FT5) +** +** Description : +** This method sets the BASEPRI core register. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */ +#ifdef _lint + #define Cpu_SetBASEPRI(Level) /* empty */ +#else +void Cpu_SetBASEPRI(uint32_t Level) { + __asm ("msr basepri, %[input]"::[input] "r" (Level):); +} +#endif +/*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + + +/* +** =================================================================== +** Method : PE_low_level_init (component MK20DX128FT5) +** +** Description : +** Initializes beans and provides common register initialization. +** The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void PE_low_level_init(void) +{ + #ifdef PEX_RTOS_INIT + PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ + #endif + /* Initialization of the SIM module */ + /* PORTA_PCR4: ISF=0,MUX=7 */ + PORTA_PCR4 = (uint32_t)((PORTA_PCR4 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK + )) | (uint32_t)( + PORT_PCR_MUX(0x07) + )); + /* Initialization of the RCM module */ + /* RCM_RPFW: RSTFLTSEL=0 */ + RCM_RPFW &= (uint8_t)~(uint8_t)(RCM_RPFW_RSTFLTSEL(0x1F)); + /* RCM_RPFC: RSTFLTSS=0,RSTFLTSRW=0 */ + RCM_RPFC &= (uint8_t)~(uint8_t)( + RCM_RPFC_RSTFLTSS_MASK | + RCM_RPFC_RSTFLTSRW(0x03) + ); + /* Initialization of the PMC module */ + /* PMC_REGSC: ACKISO=0,BGBE=0 */ + PMC_REGSC &= (uint8_t)~(uint8_t)( + PMC_REGSC_ACKISO_MASK | + PMC_REGSC_BGBE_MASK + ); + /* PMC_LVDSC1: LVDACK=1,LVDIE=0,LVDRE=1,LVDV=0 */ + PMC_LVDSC1 = (uint8_t)((PMC_LVDSC1 & (uint8_t)~(uint8_t)( + PMC_LVDSC1_LVDIE_MASK | + PMC_LVDSC1_LVDV(0x03) + )) | (uint8_t)( + PMC_LVDSC1_LVDACK_MASK | + PMC_LVDSC1_LVDRE_MASK + )); + /* PMC_LVDSC2: LVWACK=1,LVWIE=0,LVWV=0 */ + PMC_LVDSC2 = (uint8_t)((PMC_LVDSC2 & (uint8_t)~(uint8_t)( + PMC_LVDSC2_LVWIE_MASK | + PMC_LVDSC2_LVWV(0x03) + )) | (uint8_t)( + PMC_LVDSC2_LVWACK_MASK + )); + /* SMC_PMPROT: ??=0,??=0,AVLP=0,??=0,ALLS=0,??=0,AVLLS=0,??=0 */ + SMC_PMPROT = 0x00U; /* Setup Power mode protection register */ + /* Common initialization of the CPU registers */ + /* NVICIP8: PRI8=0 */ + NVICIP8 = NVIC_IP_PRI8(0x00); + MCUC1_Init(); /* ### McuLibConfig "MCUC1" init code ... */ + /* ### BitIO_LDD "BitIoLdd1" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd1_Init(NULL); + LED1_Init(); /* ### LED "LED1" init code ... */ + /* ### BitIO_LDD "BitIoLdd2" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd2_Init(NULL); + /* ### BitIO_LDD "BitIoLdd3" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd3_Init(NULL); + /* ### BitIO_LDD "BitIoLdd4" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd4_Init(NULL); + /* ### BitIO_LDD "BitIoLdd5" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd5_Init(NULL); + /* ### PWM_LDD "PwmLdd1" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)PwmLdd1_Init(NULL); + /* ### BitIO_LDD "BitIoLdd6" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd6_Init(NULL); + /* ### BitIO_LDD "BitIoLdd7" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd7_Init(NULL); + /* ### PWM_LDD "PwmLdd2" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)PwmLdd2_Init(NULL); + /* ### BitIO_LDD "BitIoLdd8" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd8_Init(NULL); + UTIL1_Init(); /* ### Utility "UTIL1" init code ... */ + /* PEX_RTOS_INIT() is a macro should already have been called either from main() + or Processor Expert startup code. So we don't call it here again. */ + /* PEX_RTOS_INIT(); */ /* ### FreeRTOS "FRTOS1" init code ... */ + WAIT1_Init(); /* ### Wait "WAIT1" init code ... */ + XF1_Init(); /* ### XFormat "XF1" init code ... */ + CS1_Init(); /* ### CriticalSection "CS1" init code ... */ + /* ### Asynchro serial "AS1" init code ... */ + AS1_Init(); + CLS1_Init(); /* ### Shell "CLS1" init code ... */ + /* ### BitIO_LDD "BitIoLdd9" component auto initialization. Auto initialization feature can be disabled by component property "Auto initialization". */ + (void)BitIoLdd9_Init(NULL); + LED2_Init(); /* ### LED "LED2" init code ... */ + HF1_Init(); /* ### HardFault "HF1" init code ... */ + KIN1_Init(); /* ### KinetisTools "KIN1" init code ... */ + RTT1_Init(); /* ### SeggerRTT "RTT1" init code ... */ + /* ### Asynchro serial "AS2" init code ... */ + AS2_Init(); +} + +/* END Cpu. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.h new file mode 100644 index 0000000..72ef3a8 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Cpu.h @@ -0,0 +1,755 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Cpu.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : MK20DX128FT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Datasheet : K20P48M50SF0RM Rev. 1, Oct 2011 +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 08:06, # CodeGen: 1 +** Abstract : +** +** Settings : +** +** Contents : +** No public methods +** +** (c) Freescale Semiconductor, Inc. +** 2004 All Rights Reserved +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Cpu.h +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Cpu_module Cpu module documentation +** @{ +*/ + +#ifndef __Cpu_H +#define __Cpu_H + +/* MODULE Cpu. */ +/*Include shared modules, which are used for whole project*/ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Active configuration define symbol */ +#define PEcfg_FLASH 1U + +/* Methods configuration constants - generated for all enabled component's methods */ + +/* Events configuration constants - generated for all enabled component's events */ +#define Cpu_OnNMIINT_EVENT_ENABLED + +#define CPU_BUS_CLK_HZ 25000000U /* Initial value of the bus clock frequency in Hz */ +#define CPU_CORE_CLK_HZ 50000000U /* Initial value of the core/system clock frequency in Hz. */ + +#define CPU_CLOCK_CONFIG_NUMBER 0x01U /* Specifies number of defined clock configurations. */ + +#define CPU_BUS_CLK_HZ_CLOCK_CONFIG0 25000000U /* Value of the bus clock frequency in the clock configuration 0 in Hz. */ +#define CPU_CORE_CLK_HZ_CLOCK_CONFIG0 50000000U /* Value of the core/system clock frequency in the clock configuration 0 in Hz. */ + + +#define CPU_XTAL_CLK_HZ 8000000U /* Value of the external crystal or oscillator clock frequency in Hz */ +#define CPU_INT_SLOW_CLK_HZ 32768U /* Value of the slow internal oscillator clock frequency in Hz */ +#define CPU_INT_FAST_CLK_HZ 4000000U /* Value of the fast internal oscillator clock frequency in Hz */ + +#define CPU_FAMILY_Kinetis /* Specification of the core type of the selected cpu */ +#define CPU_DERIVATIVE_MK20DX128FT5 /* Name of the selected cpu derivative */ +#define CPU_PARTNUM_MK20DN128VFT5 /* Part number of the selected cpu */ +#define CPU_LITTLE_ENDIAN /* The selected cpu uses little endian */ + +/* CPU frequencies in clock configuration 0 */ +#define CPU_CLOCK_CONFIG_0 0x00U /* Clock configuration 0 identifier */ +#define CPU_CORE_CLK_HZ_CONFIG_0 50000000UL /* Core clock frequency in clock configuration 0 */ +#define CPU_BUS_CLK_HZ_CONFIG_0 25000000UL /* Bus clock frequency in clock configuration 0 */ +#define CPU_FLEXBUS_CLK_HZ_CONFIG_0 0UL /* Flexbus clock frequency in clock configuration 0 */ +#define CPU_FLASH_CLK_HZ_CONFIG_0 25000000UL /* FLASH clock frequency in clock configuration 0 */ +#define CPU_USB_CLK_HZ_CONFIG_0 0UL /* USB clock frequency in clock configuration 0 */ +#define CPU_PLL_FLL_CLK_HZ_CONFIG_0 100000000UL /* PLL/FLL clock frequency in clock configuration 0 */ +#define CPU_MCGIR_CLK_HZ_CONFIG_0 32768UL /* MCG internal reference clock frequency in clock configuration 0 */ +#define CPU_OSCER_CLK_HZ_CONFIG_0 8000000UL /* System OSC external reference clock frequency in clock configuration 0 */ +#define CPU_ERCLK32K_CLK_HZ_CONFIG_0 1000UL /* External reference clock 32k frequency in clock configuration 0 */ +#define CPU_MCGFF_CLK_HZ_CONFIG_0 31250UL /* MCG fixed frequency clock */ + + +typedef struct { + uint32_t cpu_core_clk_hz; /* Core clock frequency in clock configuration */ + uint32_t cpu_bus_clk_hz; /* Bus clock frequency in clock configuration */ + uint32_t cpu_flexbus_clk_hz; /* Flexbus clock frequency in clock configuration */ + uint32_t cpu_flash_clk_hz; /* FLASH clock frequency in clock configuration */ + uint32_t cpu_usb_clk_hz; /* USB clock frequency in clock configuration */ + uint32_t cpu_pll_fll_clk_hz; /* PLL/FLL clock frequency in clock configuration */ + uint32_t cpu_mcgir_clk_hz; /* MCG internal reference clock frequency in clock configuration */ + uint32_t cpu_oscer_clk_hz; /* System OSC external reference clock frequency in clock configuration */ + uint32_t cpu_erclk32k_clk_hz; /* External reference clock 32k frequency in clock configuration */ + uint32_t cpu_mcgff_clk_hz; /* MCG fixed frequency clock */ +} TCpuClockConfiguration; + +/* The array of clock frequencies in configured clock configurations */ +extern const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER]; + + /* Interrupt vector table type definition */ + typedef void (*const tIsrFunc)(void); + typedef struct { + void * __ptr; + tIsrFunc __fun[0x3D]; + } tVectorTable; + + extern const tVectorTable __vect_table; + +/* Global variables */ +/*lint -esym(765,SR_reg) Disable MISRA rule (8.10) checking for symbols (SR_reg). The SR_reg is used in inline assembler. */ +extern volatile uint8_t SR_reg; /* Current FAULTMASK register */ +/*lint -esym(765,SR_lock) Disable MISRA rule (8.10) checking for symbols (SR_lock). The SR_reg is used in inline assembler. */ +extern volatile uint8_t SR_lock; + + +/* +** =================================================================== +** Method : PE_low_level_init (component MK20DX128FT5) +** +** Description : +** Initializes beans and provides common register initialization. +** The method is called automatically as a part of the +** application initialization code. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void PE_low_level_init(void); + +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(Cpu_INT_NMIInterrupt); +/* +** =================================================================== +** Method : Cpu_INT_NMIInterrupt (component MK20DX128FT5) +** +** Description : +** This ISR services the Non Maskable Interrupt interrupt. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Mem_Manage_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Mem_Manage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Bus_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Bus_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Usage_Fault); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Usage_Fault (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved7); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved7 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved8); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved8 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved9); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved9 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved10); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved10 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DebugMonitor); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DebugMonitor (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved13); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved13 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA2); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA3); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_DMA_Error); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_DMA_Error (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Reserved21); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Reserved21 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_FTFL); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTFL (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Read_Collision); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Read_Collision (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LVD_LVW); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LVD_LVW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LLW); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LLW (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_Watchdog); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_Watchdog (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2C0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2C0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_SPI0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SPI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2S0_Tx); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Tx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_I2S0_Rx); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_I2S0_Rx (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART0_LON); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART0_LON (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART1_RX_TX); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_RX_TX (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_UART1_ERR); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_UART1_ERR (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_ADC0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_ADC0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMP0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMP1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMP1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_FTM0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_FTM1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_FTM1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_CMT); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_CMT (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_RTC); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_RTC_Seconds); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_RTC_Seconds (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT1); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT1 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT2); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT2 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PIT3); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PIT3 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PDB0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PDB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_USB0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USB0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_USBDCD); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_USBDCD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_TSI0); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_TSI0 (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_MCG); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_MCG (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_LPTimer); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_LPTimer (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTA); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTA (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTB); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTB (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTC); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTC (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTD); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTD (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_PORTE); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_PORTE (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +PE_ISR(Cpu_ivINT_SWI); +/* +** =================================================================== +** Method : Cpu_Cpu_ivINT_SWI (component MK20DX128FT5) +** +** Description : +** This ISR services an unused interrupt/exception vector. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void __init_hardware(void); +/* +** =================================================================== +** Method : __init_hardware (component MK20DX128FT5) +** +** Description : +** Initializes the whole system like timing, external bus, etc. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +/* END Cpu. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* __Cpu_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.c new file mode 100644 index 0000000..86870d8 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : DIRA.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : DIRA +** Pin for I/O : TSI0_CH9/PTB16/UART0_RX/EWM_IN +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool DIRA_GetVal(void); +** PutVal - void DIRA_PutVal(bool Val); +** ClrVal - void DIRA_ClrVal(void); +** SetVal - void DIRA_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file DIRA.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup DIRA_module DIRA module documentation +** @{ +*/ + +/* MODULE DIRA. */ + +#include "DIRA.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : DIRA_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool DIRA_GetVal(void) + +** This method is implemented as a macro. See DIRA.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRA_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRA_PutVal(bool Val) + +** This method is implemented as a macro. See DIRA.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRA_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRA_ClrVal(void) + +** This method is implemented as a macro. See DIRA.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRA_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRA_SetVal(void) + +** This method is implemented as a macro. See DIRA.h file. ** +*/ + +/* END DIRA. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.h new file mode 100644 index 0000000..8f66f69 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRA.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : DIRA.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : DIRA +** Pin for I/O : TSI0_CH9/PTB16/UART0_RX/EWM_IN +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool DIRA_GetVal(void); +** PutVal - void DIRA_PutVal(bool Val); +** ClrVal - void DIRA_ClrVal(void); +** SetVal - void DIRA_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file DIRA.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup DIRA_module DIRA module documentation +** @{ +*/ + +#ifndef __DIRA_H +#define __DIRA_H + +/* MODULE DIRA. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd6.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : DIRA_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define DIRA_GetVal() (BitIoLdd6_GetVal(BitIoLdd6_DeviceData)) + +/* +** =================================================================== +** Method : DIRA_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define DIRA_PutVal(Val) (BitIoLdd6_PutVal(BitIoLdd6_DeviceData, (Val))) + +/* +** =================================================================== +** Method : DIRA_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define DIRA_ClrVal() (BitIoLdd6_ClrVal(BitIoLdd6_DeviceData)) + +/* +** =================================================================== +** Method : DIRA_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define DIRA_SetVal() (BitIoLdd6_SetVal(BitIoLdd6_DeviceData)) + +/* END DIRA. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __DIRA_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.c new file mode 100644 index 0000000..86a703b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : DIRB.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : DIRB +** Pin for I/O : ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/I2S0_TX_FS +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool DIRB_GetVal(void); +** PutVal - void DIRB_PutVal(bool Val); +** ClrVal - void DIRB_ClrVal(void); +** SetVal - void DIRB_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file DIRB.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup DIRB_module DIRB module documentation +** @{ +*/ + +/* MODULE DIRB. */ + +#include "DIRB.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : DIRB_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool DIRB_GetVal(void) + +** This method is implemented as a macro. See DIRB.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRB_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRB_PutVal(bool Val) + +** This method is implemented as a macro. See DIRB.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRB_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRB_ClrVal(void) + +** This method is implemented as a macro. See DIRB.h file. ** +*/ + +/* +** =================================================================== +** Method : DIRB_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void DIRB_SetVal(void) + +** This method is implemented as a macro. See DIRB.h file. ** +*/ + +/* END DIRB. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.h new file mode 100644 index 0000000..c15f250 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/DIRB.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : DIRB.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : DIRB +** Pin for I/O : ADC0_SE4b/CMP1_IN0/TSI0_CH15/PTC2/SPI0_PCS2/UART1_CTS_b/FTM0_CH1/I2S0_TX_FS +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool DIRB_GetVal(void); +** PutVal - void DIRB_PutVal(bool Val); +** ClrVal - void DIRB_ClrVal(void); +** SetVal - void DIRB_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file DIRB.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup DIRB_module DIRB module documentation +** @{ +*/ + +#ifndef __DIRB_H +#define __DIRB_H + +/* MODULE DIRB. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd7.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : DIRB_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define DIRB_GetVal() (BitIoLdd7_GetVal(BitIoLdd7_DeviceData)) + +/* +** =================================================================== +** Method : DIRB_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define DIRB_PutVal(Val) (BitIoLdd7_PutVal(BitIoLdd7_DeviceData, (Val))) + +/* +** =================================================================== +** Method : DIRB_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define DIRB_ClrVal() (BitIoLdd7_ClrVal(BitIoLdd7_DeviceData)) + +/* +** =================================================================== +** Method : DIRB_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define DIRB_SetVal() (BitIoLdd7_SetVal(BitIoLdd7_DeviceData)) + +/* END DIRB. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __DIRB_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.c new file mode 100644 index 0000000..d04d03b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.c @@ -0,0 +1,124 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ENC1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : ENC1 +** Pin for I/O : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/CMP1_OUT +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool ENC1_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ENC1.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup ENC1_module ENC1 module documentation +** @{ +*/ + +/* MODULE ENC1. */ + +#include "ENC1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : ENC1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool ENC1_GetVal(void) + +** This method is implemented as a macro. See ENC1.h file. ** +*/ + +/* END ENC1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.h new file mode 100644 index 0000000..e7dfda1 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/ENC1.h @@ -0,0 +1,136 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : ENC1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : ENC1 +** Pin for I/O : PTC4/LLWU_P8/SPI0_PCS0/UART1_TX/FTM0_CH3/CMP1_OUT +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool ENC1_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file ENC1.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup ENC1_module ENC1 module documentation +** @{ +*/ + +#ifndef __ENC1_H +#define __ENC1_H + +/* MODULE ENC1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd5.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : ENC1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define ENC1_GetVal() (BitIoLdd5_GetVal(BitIoLdd5_DeviceData)) + +/* END ENC1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __ENC1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.c new file mode 100644 index 0000000..062f613 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.c @@ -0,0 +1,4754 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:38, # CodeGen: 15 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Enabled +** Use Tick Counter : no +** LDD : Enabled +** Runtime Counter LDD : RuntimeCntrLDD +** non-LDD : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4 +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 100 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 1000 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 4000 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 1: alloc only +** Static Allocation : Disabled +** User Memory Section : Disabled +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Disabled +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** vTaskGetRunTimeStats - void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + +/* MODULE FRTOS1. */ +#include "FRTOS1.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portTicks.h" /* interface to tick counter */ +#include "RTOSCNTRLDD1.h" /* Interface to LDD Counter Interrupt */ + +#include "UTIL1.h" +#if configHEAP_SCHEME_IDENTIFICATION + /* special variable identifying the used heap scheme */ + const uint8_t freeRTOSMemoryScheme = configUSE_HEAP_SCHEME; +#endif + +uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ +LDD_TDeviceData *FRTOS1_RunTimeCounterHandle; /* runtime counter handle, used for configGENERATE_RUNTIME_STATS */ + +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pvCreatedTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskStartScheduler(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskYIELD(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENTER_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskEXIT_CRITICAL(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskDISABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_taskENABLE_INTERRUPTS(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspendAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeAll(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelay(portTickType xTicksToDelay) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType xTimeIncrement) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE uxNewPriority) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ +/* +pVoid FRTOS1_pvPortMalloc(size_t xWantedSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vPortFree(void *pv) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCount(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskGetRunTimeStats (component FreeRTOS) +** +** Description : +** configGENERATE_RUN_TIME_STATS must be defined as 1 for this +** function to be available. The application must also then +** provide definitions for +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +** portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral +** timer/counter and return the timers current count value +** respectively. The counter should be at least 10 times the +** frequency of the tick count. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. +** Setting configGENERATE_RUN_TIME_STATS to 1 will result in a +** total accumulated execution time being stored for each task. +** The resolution of the accumulated time value depends on the +** frequency of the timer configured by the +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. Calling +** vTaskGetRunTimeStats() writes the total execution time of +** each task into a buffer, both as an absolute count value and +** as a percentage of the total system execution time. +** Parameters : +** NAME - DESCRIPTION +** pcWriteBuffer - A buffer into which +** the execution times will be written, in +** ascii form. This buffer is assumed to be +** large enough to contain the generated +** report. Approximately 40 bytes per task +** should be sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +Tsize_t FRTOS1_xPortGetFreeHeapSize(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void *pvItemToQueue, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ +/* +unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void *pvBuffer, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ +/* +** =================================================================== +** Method : FRTOS1_OnCounterRestart (component FreeRTOS) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +void RTOSCNTRLDD1_OnCounterRestart(LDD_TUserData *UserDataPtr __attribute__((unused))) +{ + FRTOS1_RunTimeCounter++; /* increment runtime counter */ +} + +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ +/* +void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ +/* +bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore, signed_portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Init(void) +{ + portDISABLE_ALL_INTERRUPTS(); /* disable all interrupts, they get enabled in vStartScheduler() */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* enable clocking for low power timer, otherwise vPortStopTickTimer() will crash. + Additionally, Percepio trace needs access to the timer early on. */ + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); +#endif + vPortStopTickTimer(); /* tick timer shall not run until the RTOS scheduler is started */ +#if configUSE_PERCEPIO_TRACE_HOOKS + McuPercepio_Startup(); /* Startup Percepio Trace. Need to do this before calling any RTOS functions. */ +#endif +} + +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ +/* +xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ +/* +signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ +/* +portTickType FRTOS1_xTaskGetTickCountFromISR(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer, portTickType xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void *pvItemToQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void *pvItemToQueue, portBASE_TYPE *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ +/* +portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreate(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ +/* +byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet , BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ +/* +TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void *const pvTimerID, TimerCallbackFunction_t pxCallbackFunction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t xNewPeriod, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t xNewPeriod, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ +/* +void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t xFunctionToPend, void* pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ +/* +uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ +/* +void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery, BaseType_t xIndex) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotifyValue, BaseType_t *pxHigherPriorityTaskWoken) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ +/* +BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void FRTOS1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ +/* +char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ +/* +TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR * const pcName, unsigned portSHORT usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ +/* +xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength, unsigned_portBASE_TYPE uxItemSize, uint8_t *pucQueueStorageBuffer, StaticQueue_t *pxQueueBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ +/* +EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t *pxEventGroupBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ +/* +SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t *pxSemaphoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE uxMaxCount, unsigned_portBASE_TYPE uxInitialCount, StaticSemaphore_t pxSempahoreBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ +/* +void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ +/* +UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ +/* +xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutexStatic(StaticSemaphore_t *pxMutexBuffer) +{ + *** Implemented as macro in the header file FRTOS1.h +} +*/ + +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#if configGENERATE_RUN_TIME_STATS +void FRTOS1_AppConfigureTimerForRuntimeStats(void) +{ +#if configGENERATE_RUN_TIME_STATS_USE_TICKS + /* nothing needed, the RTOS will initialize the tick counter */ +#else + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + FRTOS1_RunTimeCounter = 0; + FRTOS1_RunTimeCounterHandle = RTOSCNTRLDD1_Init(NULL); + (void)RTOSCNTRLDD1_Enable(FRTOS1_RunTimeCounterHandle); +#endif +} + +#endif /* configGENERATE_RUN_TIME_STATS */ +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void) +{ +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + return xTaskGetTickCountFromISR(); /* using RTOS tick counter */ + #else /* using timer counter */ + extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ + return FRTOS1_RunTimeCounter; + #endif +#else + return 0; /* dummy value */ +#endif +} + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ +/* END FRTOS1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.h new file mode 100644 index 0000000..db8e04d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1.h @@ -0,0 +1,4352 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : FRTOS1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : FreeRTOS +** Version : Component 01.579, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** This component implements the FreeRTOS Realtime Operating System +** Settings : +** Component name : FRTOS1 +** RTOS Version : V10.2.1 +** SDK : MCUC1 +** Kinetis SDK : Disabled +** Custom Port : Custom port settings +** Compiler : automatic +** Source Folders : Disabled +** Custom portBASE_TYPE : Disabled +** Classic CodeWarrior : no +** Disabled Interrupts in Startup : yes +** configASSERT : yes +** Application Task Tags : no +** Thread Local Storage Pointers : 0 +** Use Trace Facility : yes +** Debug Helpers : +** Enable GDB Debug Helper : no +** uxTopUsedPriority : no +** Heap Indication Constant : no +** Segger System Viewer Trace : Disabled +** Percepio Trace : Disabled +** Generate Runtime Statistics : Enabled +** Use Tick Counter : no +** LDD : Enabled +** Runtime Counter LDD : RuntimeCntrLDD +** non-LDD : Disabled +** Scheduler : Settings for the scheduler +** ColdFire V1 : Disabled +** ColdFire V2 : Disabled +** ARM (Kinetis) : Enabled +** ARM Family : Cortex-M4 +** Max SysCall Interrupt Priority : 5 +** RTOS Interrupt Priority : 15 +** Lowest Interrupt Priority : 15 +** Compiler Optimization Level : 0 +** MPU : no +** SysTick : Enabled +** Core Clock : yes +** Low Power Timer : Disabled +** non-LDD SWI : Disabled +** Preemptive : yes +** Optimized Task Selection : yes +** Time Slicing : yes +** Use Co-Routines : no +** Idle should yield : yes +** Task Name Length : 12 +** Minimal Stack Size : 100 +** Record Stack High Address : yes +** Maximum Priorities : 6 +** Maximum Coroutine Priorities : 2 +** Stackoverflow checking method : Method 1 +** Cleanup Resources : yes +** TaskExitError Handler : no +** Ticks : Settings for the periodic tick timer +** Tickless Idle Mode : Disabled +** Tick Rate (Hz) : 1000 +** Use 16bit ticks : no +** non-LDD Tick : Disabled +** LDD Tick : Disabled +** Queues : Settings for Queues +** Queue Registry Size : 5 +** Queue Sets : no +** Semaphores and Mutexes : Settings for Mutex and Semaphore +** Use Mutexes : yes +** Use Recursive Mutexes : yes +** Timers : Disabled +** Memory : Settings for the memory and heap allocation +** Dynamic Allocation : Enabled +** Heap Size : 4000 +** Application allocated Heap : no +** Memory Allocation Scheme : Scheme 1: alloc only +** Static Allocation : Disabled +** User Memory Section : Disabled +** RTOS Adaptor : Configures the RTOS adapter settings +** Memory allocation : Configures how memory is allocated and deallocated. +** User function for memory allocation : no +** User function for memory deallocation : no +** Critical section : Configures how critical sections are handled. +** User function for entering critical section : no +** User function for exiting critical section : no +** Shell : Disabled +** Utility : UTIL1 +** Contents : +** xTaskCreate - portBASE_TYPE FRTOS1_xTaskCreate(pdTASK_CODE pvTaskCode, const portCHAR *... +** xTaskCreateStatic - TaskHandle_t FRTOS1_xTaskCreateStatic(pdTASK_CODE pvTaskCode, const portCHAR... +** vTaskStartScheduler - void FRTOS1_vTaskStartScheduler(void); +** vTaskSuspend - void FRTOS1_vTaskSuspend(xTaskHandle pxTaskToSuspend); +** vTaskSuspendAll - void FRTOS1_vTaskSuspendAll(void); +** vTaskResume - void FRTOS1_vTaskResume(xTaskHandle pxTaskToResume); +** xTaskResumeAll - portBASE_TYPE FRTOS1_xTaskResumeAll(void); +** xTaskResumeFromISR - portBASE_TYPE FRTOS1_xTaskResumeFromISR(xTaskHandle pxTaskToResume); +** taskYIELD - void FRTOS1_taskYIELD(void); +** taskENTER_CRITICAL - void FRTOS1_taskENTER_CRITICAL(void); +** taskEXIT_CRITICAL - void FRTOS1_taskEXIT_CRITICAL(void); +** taskDISABLE_INTERRUPTS - void FRTOS1_taskDISABLE_INTERRUPTS(void); +** taskENABLE_INTERRUPTS - void FRTOS1_taskENABLE_INTERRUPTS(void); +** vTaskDelay - void FRTOS1_vTaskDelay(portTickType xTicksToDelay); +** vTaskDelayUntil - void FRTOS1_vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType... +** uxTaskPriorityGet - unsigned_portBASE_TYPE FRTOS1_uxTaskPriorityGet(xTaskHandle pxTask); +** xTaskGetTickCount - portTickType FRTOS1_xTaskGetTickCount(void); +** xTaskGetTickCountFromISR - portTickType FRTOS1_xTaskGetTickCountFromISR(void); +** vTaskPrioritySet - void FRTOS1_vTaskPrioritySet(xTaskHandle pxTask, unsigned_portBASE_TYPE... +** vSemaphoreCreateBinary - void FRTOS1_vSemaphoreCreateBinary(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateBinary - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinary(void); +** xSemaphoreCreateBinaryStatic - SemaphoreHandle_t FRTOS1_xSemaphoreCreateBinaryStatic(StaticSemaphore_t... +** xSemaphoreCreateCounting - xSemaphoreHandle FRTOS1_xSemaphoreCreateCounting(unsigned_portBASE_TYPE... +** xSemaphoreCreateCountingStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateCountingStatic(unsigned_portBASE_TYPE... +** xSemaphoreGive - bool FRTOS1_xSemaphoreGive(xSemaphoreHandle xMutex); +** xSemaphoreTake - bool FRTOS1_xSemaphoreTake(xSemaphoreHandle xMutex, portTickType xBlockTime); +** uxSemaphoreGetCount - UBaseType_t FRTOS1_uxSemaphoreGetCount(SemaphoreHandle_t xSemaphore); +** xSemaphoreGiveFromISR - bool FRTOS1_xSemaphoreGiveFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreTakeFromISR - bool FRTOS1_xSemaphoreTakeFromISR(xSemaphoreHandle xSemaphore,... +** xSemaphoreGetMutexHolder - void* FRTOS1_xSemaphoreGetMutexHolder(xSemaphoreHandle xSemaphore); +** xSemaphoreCreateMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutex(void); +** xSemaphoreCreateMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreateMutexStatic(StaticSemaphore_t... +** xSemaphoreCreateRecursiveMutex - xSemaphoreHandle FRTOS1_xSemaphoreCreateRecursiveMutex(void); +** xSemaphoreCreateRecursiveMutexStatic - xSemaphoreHandle FRTOS1_xSemaphoreCreat... +** xSemaphoreTakeRecursive - bool FRTOS1_xSemaphoreTakeRecursive(xSemaphoreHandle xMutex, portTickType... +** xSemaphoreGiveRecursive - bool FRTOS1_xSemaphoreGiveRecursive(xSemaphoreHandle xMutex); +** vSemaphoreDelete - void FRTOS1_vSemaphoreDelete(xSemaphoreHandle xSemaphore); +** pvPortMalloc - pVoid FRTOS1_pvPortMalloc(size_t xWantedSize); +** vPortFree - void FRTOS1_vPortFree(void *pv); +** xPortGetFreeHeapSize - Tsize_t FRTOS1_xPortGetFreeHeapSize(void); +** xTaskGetCurrentTaskHandle - xTaskHandle FRTOS1_xTaskGetCurrentTaskHandle(void); +** xTaskGetIdleTaskHandle - xTaskHandle FRTOS1_xTaskGetIdleTaskHandle(void); +** xTaskGetHandle - TaskHandle_t FRTOS1_xTaskGetHandle(const char *pcNameToQuery ); +** pcTaskGetTaskName - signed char FRTOS1_pcTaskGetTaskName(xTaskHandle xTaskToQuery); +** xTaskGetSchedulerState - portBASE_TYPE FRTOS1_xTaskGetSchedulerState(void); +** vTaskList - void FRTOS1_vTaskList(signed portCHAR *pcWriteBuffer, size_t bufSize); +** uxTaskGetStackHighWaterMark - unsigned_portBASE_TYPE FRTOS1_uxTaskGetStackHighWaterMark(xTaskHandle xTask); +** uxTaskGetNumberOfTasks - unsigned_portBASE_TYPE FRTOS1_uxTaskGetNumberOfTasks(void); +** vTaskGetRunTimeStats - void FRTOS1_vTaskGetRunTimeStats(portCHAR *pcWriteBuffer, size_t bufSize); +** uxQueueMessagesWaiting - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaiting(xQueueHandle xQueue); +** uxQueueMessagesWaitingfromISR - unsigned_portBASE_TYPE FRTOS1_uxQueueMessagesWaitingfromISR(xQueueHandle... +** xQueueCreate - xQueueHandle FRTOS1_xQueueCreate(unsigned_portBASE_TYPE uxQueueLength,... +** xQueueCreateStatic - xQueueHandle FRTOS1_xQueueCreateStatic(unsigned_portBASE_TYPE uxQueueLength,... +** vQueueDelete - void FRTOS1_vQueueDelete(xQueueHandle pxQueueToDelete); +** xQueueReset - portBASE_TYPE FRTOS1_xQueueReset(xQueueHandle xQueue); +** xQueueSendToBack - portBASE_TYPE FRTOS1_xQueueSendToBack(xQueueHandle xQueue, const void... +** xQueueSendToFront - portBASE_TYPE FRTOS1_xQueueSendToFront(xQueueHandle xQueue, const void... +** xQueueReceive - portBASE_TYPE FRTOS1_xQueueReceive(xQueueHandle xQueue, void *pvBuffer,... +** xQueueOverwrite - portBASE_TYPE FRTOS1_xQueueOverwrite(xQueueHandle xQueue, const void... +** xQueueOverwriteFromISR - portBASE_TYPE FRTOS1_xQueueOverwriteFromISR(xQueueHandle xQueue, const void... +** xQueuePeek - portBASE_TYPE FRTOS1_xQueuePeek(xQueueHandle xQueue, void *pvBuffer,... +** xQueuePeekFromISR - portBASE_TYPE FRTOS1_xQueuePeekFromISR(xQueueHandle xQueue, void *pvBuffer,... +** xQueueSendToBackFromISR - portBASE_TYPE FRTOS1_xQueueSendToBackFromISR(xQueueHandle xQueue, const void... +** xQueueSendToFrontFromISR - portBASE_TYPE FRTOS1_xQueueSendToFrontFromISR(xQueueHandle xQueue, const void... +** xQueueReceiveFromISR - portBASE_TYPE FRTOS1_xQueueReceiveFromISR(xQueueHandle xQueue, void... +** vQueueAddToRegistry - void FRTOS1_vQueueAddToRegistry(xQueueHandle xQueue, char *pcQueueName); +** vQueueUnregisterQueue - void FRTOS1_vQueueUnregisterQueue(xQueueHandle xQueue); +** xQueueIsQueueFullFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueFullFromISR(xQueueHandle xQueue); +** xQueueIsQueueEmptyFromISR - portBASE_TYPE FRTOS1_xQueueIsQueueEmptyFromISR(xQueueHandle xQueue); +** xEventGroupCreate - EventGroupHandle_t FRTOS1_xEventGroupCreate(void); +** xEventGroupCreateStatic - EventGroupHandle_t FRTOS1_xEventGroupCreateStatic(StaticEventGroup_t... +** xEventGroupWaitBits - byte FRTOS1_xEventGroupWaitBits(const EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBits - EventBits_t FRTOS1_xEventGroupSetBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupSetBitsFromISR - EventBits_t FRTOS1_xEventGroupSetBitsFromISR(EventGroupHandle_t xEventGroup,... +** xEventGroupClearBits - EventBits_t FRTOS1_xEventGroupClearBits(EventGroupHandle_t xEventGroup, const... +** xEventGroupClearBitsFromISR - EventBits_t FRTOS1_xEventGroupClearBitsFromISR(EventGroupHandle_t... +** xEventGroupGetBits - EventBits_t FRTOS1_xEventGroupGetBits(EventGroupHandle_t xEventGroup); +** xEventGroupGetBitsFromISR - EventBits_t FRTOS1_xEventGroupGetBitsFromISR(EventGroupHandle_t xEventGroup); +** xEventGroupSync - EventBits_t FRTOS1_xEventGroupSync(EventGroupHandle_t xEventGroup, const... +** xTimerCreate - TimerHandle_t FRTOS1_xTimerCreate(const char * const pcTimerName, const... +** xTimerIsTimerActive - BaseType_t FRTOS1_xTimerIsTimerActive(TimerHandle_t xTimer); +** xTimerStart - BaseType_t FRTOS1_xTimerStart(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStop - BaseType_t FRTOS1_xTimerStop(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerChangePeriod - BaseType_t FRTOS1_xTimerChangePeriod(TimerHandle_t xTimer, TickType_t... +** xTimerDelete - BaseType_t FRTOS1_xTimerDelete(TickType_t xTimer, TickType_t xBlockTime); +** xTimerReset - BaseType_t FRTOS1_xTimerReset(TimerHandle_t xTimer, TickType_t xBlockTime); +** xTimerStartFromISR - BaseType_t FRTOS1_xTimerStartFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerStopFromISR - BaseType_t FRTOS1_xTimerStopFromISR(TimerHandle_t xTimer, BaseType_t... +** xTimerChangePeriodFromISR - BaseType_t FRTOS1_xTimerChangePeriodFromISR(TimerHandle_t xTimer, TickType_t... +** xTimerResetFromISR - BaseType_t FRTOS1_xTimerResetFromISR(TimerHandle_t xTimer, BaseType_t... +** pvTimerGetTimerID - void* FRTOS1_pvTimerGetTimerID(TimerHandle_t xTimer); +** xTimerGetTimerDaemonTaskHandle - TaskHandle_t FRTOS1_xTimerGetTimerDaemonTaskHandle(void); +** pcTimerGetTimerName - char* FRTOS1_pcTimerGetTimerName(TimerHandle_t xTimer); +** xTimerPendFunctionCall - BaseType_t FRTOS1_xTimerPendFunctionCall(PendedFunction_t xFunctionToPend,... +** xTimerPendFunctionCallFromISR - BaseType_t FRTOS1_xTimerPendFunctionCallFromISR(PendedFunction_t... +** xTaskNotifyGive - BaseType_t FRTOS1_xTaskNotifyGive(TaskHandle_t xTaskToNotify); +** vTaskNotifyGiveFromISR - void FRTOS1_vTaskNotifyGiveFromISR(TaskHandle_t xTaskToNotify, BaseType_t... +** ulTaskNotifyTake - uint32_t FRTOS1_ulTaskNotifyTake(BaseType_t xClearCountOnExit, TickType_t... +** xTaskNotify - BaseType_t FRTOS1_xTaskNotify(TaskHandle_t xTaskToNotify, uint32_t ulValue,... +** xTaskNotifyFromISR - BaseType_t FRTOS1_xTaskNotifyFromISR(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQuery - BaseType_t FRTOS1_xTaskNotifyAndQuery(TaskHandle_t xTaskToNotify, uint32_t... +** xTaskNotifyAndQueryFromISR - BaseType_t FRTOS1_xTaskNotifyAndQueryFromISR(TaskHandle_t xTaskToNotify,... +** xTaskNotifyWait - BaseType_t FRTOS1_xTaskNotifyWait(uint32_t ulBitsToClearOnEntry, uint32_t... +** xTaskNotifyStateClear - BaseType_t FRTOS1_xTaskNotifyStateClear(TaskHandle_t xTask); +** vTaskSetThreadLocalStoragePointer - void FRTOS1_vTaskSetThreadLocalStoragePointer(TaskHandle_t xTaskToSet,... +** pvTaskGetThreadLocalStoragePointer - void* FRTOS1_pvTaskGetThreadLocalStoragePointer(TaskHandle_t xTaskToQuery,... +** pcTaskGetName - char* FRTOS1_pcTaskGetName(TaskHandle_t xTaskToQuery); +** vTaskGetInfo - void FRTOS1_vTaskGetInfo(TaskHandle_t xTask, TaskStatus_t *pxTaskStatus,... +** AppConfigureTimerForRuntimeStats - void FRTOS1_AppConfigureTimerForRuntimeStats(void); +** AppGetRuntimeCounterValueFromISR - uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +** Deinit - void FRTOS1_Deinit(void); +** Init - void FRTOS1_Init(void); +** +** * FreeRTOS (c) Copyright 2003-2019 Richard Barry/Amazon, http: www.FreeRTOS.org +** * See separate FreeRTOS licensing terms. +** * +** * FreeRTOS Processor Expert Component: (c) Copyright Erich Styger, 2013-2018 +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file FRTOS1.h +** @version 01.00 +** @brief +** This component implements the FreeRTOS Realtime Operating System +*/ +/*! +** @addtogroup FRTOS1_module FRTOS1 module documentation +** @{ +*/ + + +#ifndef __FRTOS1_H +#define __FRTOS1_H + +/* MODULE FRTOS1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "FreeRTOSConfig.h" +#include "FRTOS1config.h" /* configuration file for component */ + +#if configUSE_SHELL + #include "McuShell.h" +#endif + +/* other includes needed */ +#include "FreeRTOS.h" +#include "task.h" /* task API */ +#include "semphr.h" /* semaphore API */ +#include "event_groups.h" /* event group API */ +#include "timers.h" /* timer module API */ +#include /* for size_t type */ + +#if configUSE_PERCEPIO_TRACE_HOOKS + #include "McuPercepio.h" /* Interface to Percepio Trace */ +#endif + +/* Macro for shell support */ +#define FRTOS1_PARSE_COMMAND_ENABLED (configUSE_SHELL) /* set to 1 if method ParseCommand() is present, 0 otherwise */ +#define FRTOS1_GENERATE_PEX_RTOS_MACROS 1 /* set to 1 to generate the RTOS macros PEX_RTOS_INIT() and PEX_RTOS_START() */ + +/* Macros used by Processor Expert */ +#if FRTOS1_GENERATE_PEX_RTOS_MACROS + #define PEX_RTOS_INIT() /* macro called from PE_low_level_init() */ \ + FRTOS1_Init(); + + #define PEX_RTOS_START() FRTOS1_vTaskStartScheduler() +#endif +/* macro to identify CPU: 0 for M0+ and 4 for M4 */ +#if configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 0 /* Cortex M0+ core */ +#elif configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 4 /* Cortex M4 core */ +#elif configCPU_FAMILY_IS_ARM_M7(configCPU_FAMILY) + #define FREERTOS_CPU_CORTEX_M 7 /* Cortex M7 core */ +#endif + +/* Prototypes for interrupt service handlers */ +void vPortSVCHandler(void); +void vPortPendSVHandler(void); +void vPortTickHandler(void); + +/* Version of Processor Expert (variable VersionOfPEx): 1313 */ + +#ifndef __BWUserType_Tsize_t +#define __BWUserType_Tsize_t + typedef size_t Tsize_t; /* Alias to size_t standard type */ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define FRTOS1_xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) \ + xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask) +/* +** =================================================================== +** Method : xTaskCreate (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** pvCreatedTask - Used to pass back a +** handle by which the created task can be +** referenced. +** Returns : +** --- - pdPASS if the task was successfully +** created and added to a ready list, +** otherwise an error code defined in the file +** projdefs.h +** =================================================================== +*/ + +#define FRTOS1_vTaskStartScheduler() \ + vTaskStartScheduler() +/* +** =================================================================== +** Method : vTaskStartScheduler (component FreeRTOS) +** +** Description : +** Starts the real time kernel tick processing. After calling +** the kernel has control over which tasks are executed and +** when. +** The idle task is created automatically when +** vTaskStartScheduler() is called. +** If vTaskStartScheduler() is successful the function will not +** return until an executing task calls vTaskEndScheduler(). +** The function might fail and return immediately if there is +** insufficient RAM available for the idle task to be created. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskYIELD() \ + taskYIELD() +/* +** =================================================================== +** Method : taskYIELD (component FreeRTOS) +** +** Description : +** Macro for forcing a context switch. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENTER_CRITICAL() \ + taskENTER_CRITICAL() +/* +** =================================================================== +** Method : taskENTER_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the start of a critical code region. +** Preemptive context switches cannot occur when in a critical +** region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskEXIT_CRITICAL() \ + taskEXIT_CRITICAL() +/* +** =================================================================== +** Method : taskEXIT_CRITICAL (component FreeRTOS) +** +** Description : +** Macro to mark the end of a critical code region. Preemptive +** context switches cannot occur when in a critical region. +** NOTE: This may alter the stack (depending on the portable +** implementation) so must be used with care! +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskDISABLE_INTERRUPTS() \ + taskDISABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskDISABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to disable all maskable interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_taskENABLE_INTERRUPTS() \ + taskENABLE_INTERRUPTS() +/* +** =================================================================== +** Method : taskENABLE_INTERRUPTS (component FreeRTOS) +** +** Description : +** Macro to enable microcontroller interrupts. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspendAll() \ + vTaskSuspendAll() +/* +** =================================================================== +** Method : vTaskSuspendAll (component FreeRTOS) +** +** Description : +** Suspends all real time kernel activity while keeping +** interrupts (including the kernel tick) enabled. +** After calling vTaskSuspendAll () the calling task will +** continue to execute without risk of being swapped out until +** a call to xTaskResumeAll () has been made. +** API functions that have the potential to cause a context +** switch (for example, vTaskDelayUntil(), xQueueSend(), etc.) +** must not be called while the scheduler is suspended. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeAll() \ + xTaskResumeAll() +/* +** =================================================================== +** Method : xTaskResumeAll (component FreeRTOS) +** +** Description : +** Resumes real time kernel activity following a call to +** vTaskSuspendAll (). After a call to xTaskSuspendAll () the +** kernel will take control of which task is executing at any +** time. +** Parameters : None +** Returns : +** --- - If resuming the scheduler caused a context +** switch then pdTRUE is returned, otherwise +** pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_vTaskDelay(xTicksToDelay) \ + vTaskDelay(xTicksToDelay) +/* +** =================================================================== +** Method : vTaskDelay (component FreeRTOS) +** +** Description : +** Delay a task for a given number of ticks. The actual time +** that the task remains blocked depends on the tick rate. The +** macro pdMS_TO_TICKS() can be used to calculate real time +** from the tick rate - with the resolution of one tick period. +** vTaskDelay() specifies a time at which the task wishes to +** unblock relative to the time at which vTaskDelay() is called. +** For example, specifying a block period of 100 ticks will +** cause the task to unblock 100 ticks after vTaskDelay() is +** called. vTaskDelay() does not therefore provide a good +** method of controlling the frequency of a cyclical task as +** the path taken through the code, as well as other task and +** interrupt activity, will effect the frequency at which +** vTaskDelay() gets called and therefore the time at which the +** task next executes. See vTaskDelayUntil() for an alternative +** API function designed to facilitate fixed frequency +** execution. It does this by specifying an absolute time +** (rather than a relative time) at which the calling task +** should unblock. +** Parameters : +** NAME - DESCRIPTION +** xTicksToDelay - The amount of time, in +** tick periods, that the calling task should +** block. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) \ + vTaskDelayUntil(pxPreviousWakeTime, xTimeIncrement) +/* +** =================================================================== +** Method : vTaskDelayUntil (component FreeRTOS) +** +** Description : +** Delay a task until a specified time. This function can be +** used by cyclical tasks to ensure a constant execution +** frequency. +** This function differs from vTaskDelay() in one important +** aspect: vTaskDelay() specifies a time at which the task +** wishes to unblock relative to the time at which vTaskDelay() +** is called, whereas vTaskDelayUntil() specifies an absolute +** time at which the task wishes to unblock. +** vTaskDelay() will cause a task to block for the specified +** number of ticks from the time vTaskDelay() is called. It is +** therefore difficult to use vTaskDelay() by itself to +** generate a fixed execution frequency as the time between a +** task unblocking following a call to vTaskDelay() and that +** task next calling vTaskDelay() may not be fixed [the task +** may take a different path though the code between calls, or +** may get interrupted or preempted a different number of times +** each time it executes]. +** Whereas vTaskDelay() specifies a wake time relative to the +** time at which the function is called, vTaskDelayUntil() +** specifies the absolute (exact) time at which it wishes to +** unblock. +** It should be noted that vTaskDelayUntil() will return +** immediately (without blocking) if it is used to specify a +** wake time that is already in the past. Therefore a task +** using vTaskDelayUntil() to execute periodically will have to +** re-calculate its required wake time if the periodic +** execution is halted for any reason (for example, the task is +** temporarily placed into the Suspended state) causing the +** task to miss one or more periodic executions. This can be +** detected by checking the variable passed by reference as the +** pxPreviousWakeTime parameter against the current tick count. +** This is however not necessary under most usage scenarios. +** The constant portTICK_RATE_MS can be used to calculate real +** time from the tick rate - with the resolution of one tick +** period. +** This function must not be called while the scheduler has +** been suspended by a call to vTaskSuspendAll(). +** Parameters : +** NAME - DESCRIPTION +** pxPreviousWakeTime - Pointer to a +** variable that holds the time at which the +** task was last unblocked. The variable must +** be initialised with the current time prior +** to its first use (see the example below). +** Following this the variable is +** automatically updated within +** vTaskDelayUntil(). +** xTimeIncrement - The cycle time +** period. The task will be unblocked at time +** (*pxPreviousWakeTime + xTimeIncrement). +** Calling vTaskDelayUntil with the same +** xTimeIncrement parameter value will cause +** the task to execute with a fixed interval +** period. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxTaskPriorityGet(pxTask) \ + uxTaskPriorityGet(pxTask) +/* +** =================================================================== +** Method : uxTaskPriorityGet (component FreeRTOS) +** +** Description : +** Obtain the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle of the task to be queried. +** Passing a NULL handle results in the +** priority of the calling task being returned. +** Returns : +** --- - The priority of pxTask. +** =================================================================== +*/ + +#define FRTOS1_vTaskPrioritySet(pxTask, uxNewPriority) \ + vTaskPrioritySet(pxTask, uxNewPriority) +/* +** =================================================================== +** Method : vTaskPrioritySet (component FreeRTOS) +** +** Description : +** Set the priority of any task. +** Parameters : +** NAME - DESCRIPTION +** pxTask - Handle to the task for which the +** priority is being set. Passing a NULL +** handle results in the priority of the +** calling task being set. +** uxNewPriority - The priority to which +** the task will be set. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeRecursive(xMutex, xBlockTime) \ + xSemaphoreTakeRecursive(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTakeRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively obtain, or 'take', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateRecursiveMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveRecursive(xMutex) \ + xSemaphoreGiveRecursive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGiveRecursive (component FreeRTOS) +** +** Description : +** Macro to recursively release, or 'give', a mutex type +** semaphore. The mutex must have previously been created using +** a call to xSemaphoreCreateRecursiveMutex(); +** This macro must not be used on mutexes created using +** xSemaphoreCreateMutex(). A mutex used recursively can be +** 'taken' repeatedly by the owner. The mutex doesn't become +** available again until the owner has called +** xSemaphoreGiveRecursive() for each successful 'take' request. +** For example, if a task successfully 'takes' the same mutex 5 +** times then the mutex will not be available to any other task +** until it has also 'given' the mutex back exactly five times. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutex() \ + xSemaphoreCreateRecursiveMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutex (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskSuspend(pxTaskToSuspend) \ + vTaskSuspend(pxTaskToSuspend) + +/* +** =================================================================== +** Method : vTaskSuspend (component FreeRTOS) +** +** Description : +** Suspend any task. When suspended a task will never get any +** microcontroller processing time, no matter what its priority. +** Calls to vTaskSuspend are not accumulative - i.e. calling +** vTaskSuspend() twice on the same task still only requires +** one call to vTaskResume() to ready the suspended task. +** Parameters : +** NAME - DESCRIPTION +** pxTaskToSuspend - Handle to the task +** being suspended. Passing a NULL handle will +** cause the calling task to be suspended. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskResume(pxTaskToResume) \ + vTaskResume(pxTaskToResume) + +/* +** =================================================================== +** Method : vTaskResume (component FreeRTOS) +** +** Description : +** Resumes a suspended task. A task that has been suspended by +** one of more calls to vTaskSuspend() will be made available +** for running again by a single call to vTaskResume(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutex() \ + xSemaphoreCreateMutex() + +/* +** =================================================================== +** Method : xSemaphoreCreateMutex (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : None +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTake(xMutex, xBlockTime) \ + xSemaphoreTake(xMutex, xBlockTime) + +/* +** =================================================================== +** Method : xSemaphoreTake (component FreeRTOS) +** +** Description : +** Macro to obtain a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(). +** This macro must not be called from an ISR. +** xQueueReceiveFromISR() can be used to take a semaphore from +** within an interrupt if required, although this would not be +** a normal operation. Semaphores use queues as their +** underlying mechanism, so functions are to some extent +** interoperable. +** xSemaphoreTake() is part of the fully featured intertask +** communications API. xSemaphoreAltTake() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being obtained. +** This is the handle returned by +** xSemaphoreCreateMutex(); +** xBlockTime - The time in ticks to wait +** for the semaphore to become available. The +** macro portTICK_RATE_MS can be used to +** convert this to a real time. A block time +** of zero can be used to poll the semaphore. +** If the task already owns the semaphore then +** xSemaphoreTakeRecursive() will return +** immediately no matter what the value of +** xBlockTime. Specifying the block time as +** portMAX_DELAY will cause the task to block +** indefinitely (without a timeout). +** Returns : +** --- - Returns pdTRUE if the semaphore was +** obtained. pdFALSE if xBlockTime expired +** without the semaphore becoming available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGive(xMutex) \ + xSemaphoreGive(xMutex) + +/* +** =================================================================== +** Method : xSemaphoreGive (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary(), xSemaphoreCreateMutex() or +** xSemaphoreCreateCounting(), and obtained using +** sSemaphoreTake(). +** This must not be used from an ISR. See +** xSemaphoreGiveFromISR() for an alternative which can be used +** from an ISR. +** This macro must also not be used on semaphores created using +** xSemaphoreCreateRecursiveMutex(). +** xSemaphoreGive() is part of the fully featured intertask +** communications API. xSemaphoreAltGive() is the alternative +** API equivalent. Both versions require the same parameters +** and return the same values. +** Parameters : +** NAME - DESCRIPTION +** xMutex - A handle to the mutex being released, +** or 'given'. This is the handle returned by +** xSemaphoreCreateMutex(); +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreCreateBinary(xSemaphore) \ + vSemaphoreCreateBinary(xSemaphore) + +/* +** =================================================================== +** Method : vSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** Macro that creates a semaphore by using the existing queue +** mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as we don't want to actually +** store any data - we just want to know if the queue is empty +** or full. +** Binary semaphores and mutexes are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** This old vSemaphoreCreateBinary() macro is now deprecated in +** favour of the xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - Handle to the created +** semaphore. Should be of type +** xSemaphoreHandle. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) \ + xSemaphoreCreateCounting(uxMaxCount, uxInitialCount) + +/* +** =================================================================== +** Method : xSemaphoreCreateCounting (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreGiveFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreGiveFromISR (component FreeRTOS) +** +** Description : +** Macro to release a semaphore. The semaphore must have +** previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being released. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** giving the semaphoree caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreGiveFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +#define FRTOS1_vSemaphoreDelete(xSemaphore) \ + vSemaphoreDelete(xSemaphore) +/* +** =================================================================== +** Method : vSemaphoreDelete (component FreeRTOS) +** +** Description : +** Delete a semaphore. This function must be used with care. +** For example, do not delete a mutex type semaphore if the +** mutex is held by a task. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore to +** be deleted. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vTaskList(pcWriteBuffer, bufSize) \ + vTaskList(pcWriteBuffer, bufSize) + +/* +** =================================================================== +** Method : vTaskList (component FreeRTOS) +** +** Description : +** configUSE_TRACE_FACILITY, INCLUDE_vTaskDelete and +** INCLUDE_vTaskSuspend must all be defined as 1 for this +** function to be available. See the configuration section for +** more information. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. Lists all the current tasks, along with their +** current state and stack usage high water mark. +** Tasks are reported as blocked ('B'), ready ('R'), deleted +** ('D') or suspended ('S'). +** Parameters : +** NAME - DESCRIPTION +** * pcWriteBuffer - Pointer to buffer. A +** buffer into which the above mentioned +** details will be written, in ascii form. +** This buffer is assumed to be large enough +** to contain the generated report. +** Approximately 40 bytes per task should be +** sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvPortMalloc(xWantedSize) \ + pvPortMalloc(xWantedSize) +/* +** =================================================================== +** Method : pvPortMalloc (component FreeRTOS) +** +** Description : +** Allocates a memory block using the port pvPortMalloc() +** function +** Parameters : +** NAME - DESCRIPTION +** xWantedSize - size of memory block +** requested +** Returns : +** --- - memory block or NULL if failed +** =================================================================== +*/ + +#define FRTOS1_vPortFree(pv) \ + vPortFree(pv) +/* +** =================================================================== +** Method : vPortFree (component FreeRTOS) +** +** Description : +** Frees a memory block previously allocated with pvPortMalloc() +** Parameters : +** NAME - DESCRIPTION +** * pv - Pointer to data +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCount() \ + xTaskGetTickCount() +/* +** =================================================================== +** Method : xTaskGetTickCount (component FreeRTOS) +** +** Description : +** Return the count of ticks since vTaskStartScheduler was +** called. +** Parameters : None +** Returns : +** --- - tick count +** =================================================================== +*/ + +#define FRTOS1_xTaskGetSchedulerState() \ + xTaskGetSchedulerState() +/* +** =================================================================== +** Method : xTaskGetSchedulerState (component FreeRTOS) +** +** Description : +** Returns the state of the scheduler +** Parameters : None +** Returns : +** --- - One of the following constants (defined +** within task.h): taskSCHEDULER_NOT_STARTED, +** taskSCHEDULER_RUNNING, +** taskSCHEDULER_SUSPENDED. +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetStackHighWaterMark(xTask) \ + uxTaskGetStackHighWaterMark(xTask) +/* +** =================================================================== +** Method : uxTaskGetStackHighWaterMark (component FreeRTOS) +** +** Description : +** The stack used by a task will grow and shrink as the task +** executes and interrupts are processed. +** uxTaskGetStackHighWaterMark() returns the minimum amount of +** remaining stack space that was available to the task since +** the task started executing - that is the amount of stack +** that remained unused when the task stack was at its greatest +** (deepest) value. This is what is referred to as the stack +** 'high water mark'. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** A task may query its own high water mark by +** passing NULL as the xTask parameter. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_uxTaskGetNumberOfTasks() \ + uxTaskGetNumberOfTasks() +/* +** =================================================================== +** Method : uxTaskGetNumberOfTasks (component FreeRTOS) +** +** Description : +** Returns the number of tasks +** Parameters : None +** Returns : +** --- - number of tasks +** =================================================================== +*/ + +#define FRTOS1_vTaskGetRunTimeStats(pcWriteBuffer, bufSize) \ + vTaskGetRunTimeStats(pcWriteBuffer, bufSize) + +/* +** =================================================================== +** Method : vTaskGetRunTimeStats (component FreeRTOS) +** +** Description : +** configGENERATE_RUN_TIME_STATS must be defined as 1 for this +** function to be available. The application must also then +** provide definitions for +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +** portGET_RUN_TIME_COUNTER_VALUE to configure a peripheral +** timer/counter and return the timers current count value +** respectively. The counter should be at least 10 times the +** frequency of the tick count. +** NOTE: This function will disable interrupts for its duration. +** It is not intended for normal application runtime use but as +** a debug aid. +** Setting configGENERATE_RUN_TIME_STATS to 1 will result in a +** total accumulated execution time being stored for each task. +** The resolution of the accumulated time value depends on the +** frequency of the timer configured by the +** portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. Calling +** vTaskGetRunTimeStats() writes the total execution time of +** each task into a buffer, both as an absolute count value and +** as a percentage of the total system execution time. +** Parameters : +** NAME - DESCRIPTION +** pcWriteBuffer - A buffer into which +** the execution times will be written, in +** ascii form. This buffer is assumed to be +** large enough to contain the generated +** report. Approximately 40 bytes per task +** should be sufficient. +** bufSize - size of buffer +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xPortGetFreeHeapSize() \ + xPortGetFreeHeapSize() + +/* +** =================================================================== +** Method : xPortGetFreeHeapSize (component FreeRTOS) +** +** Description : +** Returns the actual free size of the heap +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xQueueCreate(uxQueueLength, uxItemSize) \ + xQueueCreate(uxQueueLength, uxItemSize) +/* +** =================================================================== +** Method : xQueueCreate (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToFront(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToFront (component FreeRTOS) +** +** Description : +** Sends an item to the front of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) \ + xQueueSendToBack(xQueue, pvItemToQueue, xTicksToWait) +/* +** =================================================================== +** Method : xQueueSendToBack (component FreeRTOS) +** +** Description : +** Sends an item to the back of a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for space to +** become available on the queue should the +** queue already be full. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for space to become available on the queue. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceive(xQueue, pvBuffer, xTicksToWait) \ + xQueueReceive(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueueReceive (component FreeRTOS) +** +** Description : +** Receives an item from a queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied. +** The length of the buffer must be at least +** equal to the queue item size (set when the +** queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeek(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeek(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeek (component FreeRTOS) +** +** Description : +** Reads an item from a queue, but does not remove the item +** from the queue. Therefore the same item would be returned +** the next time xQueueReceive() or xQueuePeek() was called on +** the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_vQueueDelete(pxQueueToDelete) \ + vQueueDelete(pxQueueToDelete) +/* +** =================================================================== +** Method : vQueueDelete (component FreeRTOS) +** +** Description : +** Deletes a queue that was previously created using a call to +** xQueueCreate(). vQueueDelete() can also be used to delete a +** semaphore. +** Parameters : +** NAME - DESCRIPTION +** pxQueueToDelete - The handle of the +** queue being deleted. Semaphore handles can +** also be used. Queues are used to pass data +** between tasks and between tasks and +** interrupts. A queue/semaphore must not be +** deleted if there are any tasks that are +** blocked on the queue/semaphore waiting for +** events (sends or receives). +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaiting(xQueue) \ + uxQueueMessagesWaiting(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaiting (component FreeRTOS) +** +** Description : +** Queries the number of items that are currently held within a +** queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_uxQueueMessagesWaitingfromISR(xQueue) \ + uxQueueMessagesWaitingfromISR(xQueue) +/* +** =================================================================== +** Method : uxQueueMessagesWaitingfromISR (component FreeRTOS) +** +** Description : +** A version of uxQueueMessagesWaiting() that can be used from +** inside an interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - The number of items that are held within +** the queue being queried. +** =================================================================== +*/ + +#define FRTOS1_xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) \ + xQueueReceiveFromISR(xQueue, pvBuffer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueReceiveFromISR (component FreeRTOS) +** +** Description : +** A version of xQueueReceive() that can be called from an ISR. +** Unlike xQueueReceive(), xQueueReceiveFromISR() does not +** permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be received. +** pvBuffer - A pointer to the memory into +** which the data received from the queue will +** be copied.The length of the buffer must be +** at least equal to the queue item size (set +** when the queue was created). +** * pxHigherPriorityTaskWoken +** - Pointer to A task may be blocked waiting +** for space to become available on the queue. +** If xQueueReceiveFromISR() causes such a +** task to unblock then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE, otherwise +** *pxHigherPriorityTaskWoken will remain +** unchanged. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueSendToFrontFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToFrontFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToFront() API functions that can be +** called from an ISR. Unlike xQueueSendToFront() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) \ + xQueueSendToBackFromISR(xQueue, pvItemToQueue,pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueSendToBackFromISR (component FreeRTOS) +** +** Description : +** Versions of xQueueSendToBack() API functions that can be +** called from an ISR. Unlike xQueueSendToBack() these +** functions do not permit a block time to be specified. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_xTaskResumeFromISR(pxTaskToResume) \ + xTaskResumeFromISR(pxTaskToResume) + +/* +** =================================================================== +** Method : xTaskResumeFromISR (component FreeRTOS) +** +** Description : +** An implementation of vTaskResume() that can be called from +** within an ISR. A task that has been suspended by one of more +** calls to vTaskSuspend() will be made available for running +** again by a single call to xTaskResumeFromISR(). +** Parameters : +** NAME - DESCRIPTION +** pxTaskToResume - Handle to the task +** being readied. +** Returns : +** --- - Error code +** =================================================================== +*/ + +extern uint32_t FRTOS1_RunTimeCounter; /* runtime counter, used for configGENERATE_RUNTIME_STATS */ +extern LDD_TDeviceData *FRTOS1_RunTimeCounterHandle; /* runtime counter handle, used for configGENERATE_RUNTIME_STATS */ +void RTOSCNTRLDD1_OnCounterRestart(LDD_TUserData *UserDataPtr); + +#define FRTOS1_xQueueReset(xQueue) \ + xQueueReset(xQueue) + +/* +** =================================================================== +** Method : xQueueReset (component FreeRTOS) +** +** Description : +** Reset a queue back to its original empty state. pdPASS is +** returned if the queue is successfully reset. pdFAIL is +** returned if the queue could not be reset because there are +** tasks blocked on the queue waiting to either receive from +** the queue or send to the queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to reset. +** Returns : +** --- - pdPASS is returned if the queue is +** successfully reset. pdFAIL is returned if +** the queue could not be reset because there +** are tasks blocked on the queue waiting to +** either receive from the queue or send to +** the queue. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreGetMutexHolder(xSemaphore) \ + xSemaphoreGetMutexHolder(xSemaphore) + +/* +** =================================================================== +** Method : xSemaphoreGetMutexHolder (component FreeRTOS) +** +** Description : +** Returns the holder of a mutex or semaphore. If xMutex is +** indeed a mutex type semaphore, return the current mutex +** holder. If xMutex is not a mutex type semaphore, or the +** mutex is available (not held by a task), return NULL. Note: +** This Is is a good way of determining if the calling task is +** the mutex holder, but not a good way of determining the +** identity of the mutex holder as the holder may change +** between the function exiting and the returned value being +** tested. +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore. +** Returns : +** --- - Not NULL if the calling task is the holder +** of the mutex, NULL otherwise. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) \ + xSemaphoreTakeFromISR(xSemaphore, pxHigherPriorityTaskWoken) + +/* +** =================================================================== +** Method : xSemaphoreTakeFromISR (component FreeRTOS) +** +** Description : +** Macro to take a semaphore from an ISR. The semaphore must +** have previously been created with a call to +** vSemaphoreCreateBinary() or xSemaphoreCreateCounting(). +** Mutex type semaphores (those created using a call to +** xSemaphoreCreateMutex()) must not be used with this macro. +** This macro can be used from an ISR, however taking a +** semaphore from an ISR is not a common operation. It is +** likely to only be useful when taking a counting semaphore +** when an interrupt is obtaining an object from a resource +** pool (when the semaphore count indicates the number of +** resources available). +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - A handle to the semaphore +** being taken. This is the handle returned +** when the semaphore was created. +** * pxHigherPriorityTaskWoken +** - xSemaphoreTakeFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** taking the semaphore caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xSemaphoreTakeFromISR() sets this +** value to pdTRUE then a context switch +** should be requested before the interrupt is +** exited. +** Returns : +** --- - Returns pdTRUE if the semaphore was given. +** =================================================================== +*/ + +void FRTOS1_Init(void); +/* +** =================================================================== +** Method : Init (component FreeRTOS) +** +** Description : +** Low level initialization routine called from startup code. +** This method ensures that the tick timer is not enabled. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetCurrentTaskHandle() \ + xTaskGetCurrentTaskHandle() +/* +** =================================================================== +** Method : xTaskGetCurrentTaskHandle (component FreeRTOS) +** +** Description : +** The handle of the currently running (calling) task. +** Parameters : None +** Returns : +** --- - The handle of the currently running +** (calling) task. +** =================================================================== +*/ + +#define FRTOS1_xTaskGetIdleTaskHandle() \ + xTaskGetIdleTaskHandle() +/* +** =================================================================== +** Method : xTaskGetIdleTaskHandle (component FreeRTOS) +** +** Description : +** The task handle associated with the Idle task. The Idle task +** is created automatically when the RTOS scheduler is started. +** Parameters : None +** Returns : +** --- - The task handle associated with the Idle +** task. The Idle task is created +** automatically when the RTOS scheduler is +** started. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetTaskName(xTaskToQuery) \ + pcTaskGetTaskName(xTaskToQuery) +/* +** =================================================================== +** Method : pcTaskGetTaskName (component FreeRTOS) +** +** Description : +** Returns the name of the task. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject tasks name, which +** is a standard NULL terminated C string +** =================================================================== +*/ + +#define FRTOS1_xTaskGetTickCountFromISR() \ + xTaskGetTickCountFromISR() +/* +** =================================================================== +** Method : xTaskGetTickCountFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskGetTickCount() that can be called from an +** ISR. +** Parameters : None +** Returns : +** --- - The count of ticks since +** vTaskStartScheduler was called. +** =================================================================== +*/ + +#define FRTOS1_xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) \ + xQueuePeekFromISR(xQueue, pvBuffer, xTicksToWait) +/* +** =================================================================== +** Method : xQueuePeekFromISR (component FreeRTOS) +** +** Description : +** A version of xQueuePeek() that can be used from an interrupt +** service routine (ISR). Reads an item from a queue, but does +** not remove the item from the queue. Therefore the same item +** would be returned the next time xQueueReceive() or +** xQueuePeek() was called on the same queue. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue from which +** the data is to be read. +** pvBuffer - A pointer to the memory into +** which the data read from the queue will be +** copied. The length of the buffer must be at +** least equal to the queue item size (set +** when the queue was created). +** xTicksToWait - The number of ticks for +** which the calling task should be held in +** the Blocked state to wait for data to +** become available from the queue should the +** queue already be empty. +** A value of zero will prevent the calling +** task from entering the Blocked state. +** If INCLUDE_vTaskSuspend is set to 1 then a +** value of portMAX_DELAY will hold the task +** in the Blocked state indefinitely to wait +** for data. +** Returns : +** --- - pdPASS: Data was successfully read from +** the queue. If a block time was specified +** then the calling task may have been +** temporarily placed into the Blocked state +** to wait for data to become available and +** data did become available before the block +** time expired. +** errQUEUE_EMPTY: The queue was empty so no +** date could be read form the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for data to +** become available, but no data became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwrite(xQueue, pvItemToQueue) \ + xQueueOverwrite(xQueue, pvItemToQueue) +/* +** =================================================================== +** Method : xQueueOverwrite (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSend() function. +** A version of xQueueSendToBack() that will write to the queue +** even if the queue is full, overwriting data that is already +** held in the queue. xQueueOverwrite() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. This function must not be called from +** an interrupt service routine (ISR). See +** xQueueOverwriteFromISR() for an alternative which may be +** used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** Returns : +** --- - pdPASS: Data was successfully sent to the +** queue. If a block time was specified then +** the calling task may have been temporarily +** placed into the Blocked state to wait for +** space to become available and space did +** become available before the block time +** expired. +** errQUEUE_FULL: The queue is already full so +** no data could be sent to the queue. If a +** block time was specified then the calling +** task may have been temporarily placed into +** the Blocked state to wait for space to +** become available, but no space became +** available before the block time expired. +** =================================================================== +*/ + +#define FRTOS1_xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) \ + xQueueOverwriteFromISR(xQueue, pvItemToQueue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xQueueOverwriteFromISR (component FreeRTOS) +** +** Description : +** This is a macro that calls the xQueueGenericSendFromISR() +** function. A version of xQueueOverwrite() that can be used in +** an ISR. xQueueOverwriteFromISR() is similar to +** xQueueSendToBackFromISR(), but will write to the queue even +** if the queue is full, overwriting data that is already held +** in the queue. xQueueOverwriteFromISR() is intended for use +** with queues that have a length of one, meaning the queue is +** either empty or full. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue to which the +** data is to be sent. +** pvItemToQueue - A pointer to the data +** to be sent to the queue. The size of the +** data that can be sent to a queue was +** defined when the queue was created. +** * pxHigherPriorityTaskWoken +** - xQueueSendFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending to the queue caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. If xQueueSendFromISR() sets this +** value to pdTRUE then a context switch +** should be performed before the interrupt is +** exited. +** Returns : +** --- - pdTRUE Data was successfully sent to the +** queue. +** errQUEUE_FULL Data could not be sent to the +** queue because the queue was already full. +** =================================================================== +*/ + +#define FRTOS1_vQueueAddToRegistry(xQueue, pcQueueName) \ + vQueueAddToRegistry(xQueue, pcQueueName) +/* +** =================================================================== +** Method : vQueueAddToRegistry (component FreeRTOS) +** +** Description : +** Assigns a name to a queue and adds the queue to the registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being added +** to the registry. +** * pcQueueName - Pointer to the name to be +** assigned to the queue. This is just a text +** string used to facilitate debugging. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_vQueueUnregisterQueue(xQueue) \ + vQueueUnregisterQueue(xQueue) +/* +** =================================================================== +** Method : vQueueUnregisterQueue (component FreeRTOS) +** +** Description : +** Removes a queue from the queue registry. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** removed from the registry. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueFullFromISR(xQueue) \ + xQueueIsQueueFullFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueFullFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is full. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not full, or any +** other value if the queue is full. +** =================================================================== +*/ + +#define FRTOS1_xQueueIsQueueEmptyFromISR(xQueue) \ + xQueueIsQueueEmptyFromISR(xQueue) +/* +** =================================================================== +** Method : xQueueIsQueueEmptyFromISR (component FreeRTOS) +** +** Description : +** Queries a queue to determine if the queue is empty. This +** function should only be used in an ISR. +** Parameters : +** NAME - DESCRIPTION +** xQueue - The handle of the queue being +** queried. +** Returns : +** --- - pdFALSE if the queue is not empty, or any +** other value if the queue is empty. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreate() \ + xEventGroupCreate() +/* +** =================================================================== +** Method : xEventGroupCreate (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : None +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) \ + xEventGroupWaitBits(xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupWaitBits (component FreeRTOS) +** +** Description : +** Read bits within an RTOS event group, optionally entering +** the Blocked state (with a timeout) to wait for a bit or +** group of bits to become set. This function cannot be called +** from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being tested. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, to +** wait for bit 0 and/or bit 2 set +** uxBitsToWaitFor to 0x05. To wait for bits 0 +** and/or bit 1 and/or bit 2 set +** uxBitsToWaitFor to 0x07. Etc. +** uxBitsToWaitFor must not be set to 0. +** xClearOnExit - If xClearOnExit is set +** to pdTRUE then any bits set in the value +** passed as the uxBitsToWaitFor parameter +** will be cleared in the event group before +** xEventGroupWaitBits() returns if +** xEventGroupWaitBits() returns for any +** reason other than a timeout. The timeout +** value is set by the xTicksToWait parameter. +** If xClearOnExit is set to pdFALSE then the +** bits set in the event group are not altered +** when the call to xEventGroupWaitBits() +** returns. +** xWaitForAllBits - xWaitForAllBits is +** used to create either a logical AND test +** (where all bits must be set) or a logical +** OR test (where one or more bits must be set) +** as follows: +** If xWaitForAllBits is set to pdTRUE then +** xEventGroupWaitBits() will return when +** either all the bits set in the value passed +** as the uxBitsToWaitFor parameter are set in +** the event group or the specified block time +** expires. +** If xWaitForAllBits is set to pdFALSE then +** xEventGroupWaitBits() will return when any +** of the bits set in the value passed as the +** uxBitsToWaitFor parameter are set in the +** event group or the specified block time +** expires. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for +** one/all (depending on the xWaitForAllBits +** value) of the bits specified by +** uxBitsToWaitFor to become set. +** Returns : +** --- - EventBits_t: The value of the event group +** at the time either the event bits being +** waited for became set, or the block time +** expired. The current value of the event +** bits in an event group will be different to +** the returned value if a higher priority +** task or interrupt changed the value of an +** event bit between the calling task leaving +** the Blocked state and exiting the +** xEventGroupWaitBits() function. +** Test the return value to know which bits +** were set. If xEventGroupWaitBits() returned +** because its timeout expired then not all +** the bits being waited for will be set. If +** xEventGroupWaitBits() returned because the +** bits it was waiting for were set then the +** returned value is the event group value +** before any bits were automatically cleared +** because the xClearOnExit parameter was set +** to pdTRUE. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBits(xEventGroup, uxBitsToSet) \ + xEventGroupSetBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupSetBits (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. +** xEventGroupSetBitsFromISR() is a version that can be called +** from an interrupt. +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) \ + xEventGroupSetBitsFromISR(xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xEventGroupSetBitsFromISR (component FreeRTOS) +** +** Description : +** Set bits (flags) within an RTOS event group. A version of +** xEventGroupSetBits() that can be called from an interrupt +** service routine (ISR). +** Setting bits in an event group will automatically unblock +** tasks that are blocked waiting for the bits. +** Setting bits in an event group is not a deterministic +** operation because there are an unknown number of tasks that +** may be waiting for the bit or bits being set. FreeRTOS does +** not allow non-deterministic operations to be performed in +** interrupts or from critical sections. Therefore +** xEventGroupSetBitFromISR() sends a message to the RTOS +** daemon task to have the set operation performed in the +** context of the daemon task - where a scheduler lock is used +** in place of a critical section. +** INCLUDE_xEventGroupSetBitFromISR, configUSE_TIMERS and +** INCLUDE_xTimerPendFunctionCall must all be set to 1 in +** FreeRTOSConfig.h for the xEventGroupSetBitsFromISR() +** function to be available. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** pxHigherPriorityTaskWoken +** - Calling this function will result in a +** message being sent to the RTOS daemon task. +** If the priority of the daemon task is +** higher than the priority of the currently +** running task (the task the interrupt +** interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE by xEventGroupSetBitsFromISR(), +** indicating that a context switch should be +** requested before the interrupt exits. For +** that reason *pxHigherPriorityTaskWoken must +** be initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBits(xEventGroup, uxBitsToSet) \ + xEventGroupClearBits(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBits (component FreeRTOS) +** +** Description : +** Clear bits (flags) within an RTOS event group. This function +** cannot be called from an interrupt. See +** xEventGroupClearBitsFromISR() for a version that can be +** called from an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be cleared. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to clear in the +** event group. For example set uxBitsToClear +** to 0x08 to clear just bit 3. Set +** uxBitsToClear to 0x09 to clear bit 3 and +** bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) \ + xEventGroupClearBitsFromISR(xEventGroup, uxBitsToSet) +/* +** =================================================================== +** Method : xEventGroupClearBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupClearBits() that can be called from +** an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are to be set. The event group +** must have previously been created using a +** call to xEventGroupCreate(). +** uxBitsToSet - A bitwise value that +** indicates the bit or bits to set in the +** event group. For example, set uxBitsToSet +** to 0x08 to set only bit 3. Set uxBitsToSet +** to 0x09 to set bit 3 and bit 0. +** Returns : +** --- - The value of the event group at the time +** the call to xEventGroupSetBits() returns. +** There are two reasons why the returned +** value might have the bits specified by the +** uxBitsToSet parameter cleared: +** If setting a bit results in a task that was +** waiting for the bit leaving the blocked +** state then it is possible the bit will have +** been cleared automatically (see the +** xClearBitOnExit parameter of +** xEventGroupWaitBits()). +** Any unblocked (or otherwise Ready state) +** task that has a priority above that of the +** task that called xEventGroupSetBits() will +** execute and may change the event group +** value before the call to +** xEventGroupSetBits() returns. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBits(xEventGroup) \ + xEventGroupGetBits(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBits (component FreeRTOS) +** +** Description : +** Returns the current value of the event bits (event flags) in +** an RTOS event group. This function cannot be used from an +** interrupt. See xEventGroupsGetBitsFromISR() for a version +** that can be used in an interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupGetBitsFromISR(xEventGroup) \ + xEventGroupGetBitsFromISR(xEventGroup) +/* +** =================================================================== +** Method : xEventGroupGetBitsFromISR (component FreeRTOS) +** +** Description : +** A version of xEventGroupGetBits() that can be called from an +** interrupt. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group being +** queried. The event group must have +** previously been created using a call to +** xEventGroupCreate(). +** Returns : +** --- - The value of the event bits in the event +** group at the time xEventGroupGetBits() was +** called. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) \ + xEventGroupSync(xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait) +/* +** =================================================================== +** Method : xEventGroupSync (component FreeRTOS) +** +** Description : +** Atomically set bits (flags) within an RTOS event group, +** then wait for a combination of bits to be set within the +** same event group. This functionality is typically used to +** synchronise multiple tasks (often called a task rendezvous), +** where each task has to wait for the other tasks to reach a +** synchronisation point before proceeding. +** This function cannot be used from an interrupt. +** The function will return before its block time expires if +** the bits specified by the uxBitsToWait parameter are set, or +** become set within that time. In this case all the bits +** specified by uxBitsToWait will be automatically cleared +** before the function returns. +** Parameters : +** NAME - DESCRIPTION +** xEventGroup - The event group in which +** the bits are being set and tested. The +** event group must have previously been +** created using a call to xEventGroupCreate(). +** uxBitsToSet - The bit or bits to set in +** the event group before determining if (and +** possibly waiting for), all the bits +** specified by the uxBitsToWait parameter are +** set. For example, set uxBitsToSet to 0x04 +** to set bit 2 within the event group. +** uxBitsToWaitFor - A bitwise value +** that indicates the bit or bits to test +** inside the event group. For example, set +** uxBitsToWaitFor to 0x05 to wait for bits 0 +** and bit 2. Set uxBitsToWaitFor to 0x07 to +** wait for bit 0 and bit 1 and bit 2. Etc. +** xTicksToWait - The maximum amount of +** time (specified in 'ticks') to wait for all +** the bits specified by the uxBitsToWaitFor +** parameter value to become set. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) \ + xTimerCreate(pcTimerName, xTimerPeriod, uxAutoReload, pvTimerID, pxCallbackFunction) +/* +** =================================================================== +** Method : xTimerCreate (component FreeRTOS) +** +** Description : +** Creates a new software timer instance. This allocates the +** storage required by the new timer, initialises the new +** timers internal state, and returns a handle by which the new +** timer can be referenced. +** Parameters : +** NAME - DESCRIPTION +** pcTimerName - +** Atextnamethatisassignedtothetimer_Thisisdone +** purelytoassistdebugging_TheRTOSkernelitselfo +** nlyeverreferencesatimerbyitshandle_andneverb +** yitsname_ +** xTimerPeriod - The timer period. The +** time is defined in tick periods so the +** constant portTICK_PERIOD_MS can be used to +** convert a time that has been specified in +** milliseconds. For example, if the timer +** must expire after 100 ticks, then +** xTimerPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xPeriod can be set to ( +** 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** uxAutoReload - If uxAutoReload is set +** to pdTRUE, then the timer will expire +** repeatedly with a frequency set by the +** xTimerPeriod parameter. If uxAutoReload is +** set to pdFALSE, then the timer will be a +** one-shot and enter the dormant state after +** it expires. +** pvTimerID - An identifier that is assigned +** to the timer being created. Typically this +** would be used in the timer callback +** function to identify which timer expired +** when the same callback function is assigned +** to more than one timer. +** pxCallbackFunction - The function +** to call when the timer expires. Callback +** functions must have the prototype defined +** by TimerCallbackFunction_t, which is "void +** vCallbackFunction( TimerHandle_t xTimer );". +** Returns : +** --- - Timer handle. If the timer is successfully +** created then a handle to the newly created +** timer is returned. If the timer cannot be +** created (because either there is +** insufficient FreeRTOS heap remaining to +** allocate the timer structures, or the timer +** period was set to 0) then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerIsTimerActive(xTimer) \ + xTimerIsTimerActive(xTimer) +/* +** =================================================================== +** Method : xTimerIsTimerActive (component FreeRTOS) +** +** Description : +** Queries a timer to see if it is active or dormant. +** A timer will be dormant if: +** It has been created but not started, or +** It is an expired one-shot timer that has not been restarted. +** Timers are created in the dormant state. The xTimerStart(), +** xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions can all be used to transition a timer into the +** active state. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xTimerStart(xTimer, xBlockTime) \ + xTimerStart(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStart (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStart() starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerStart() has equivalent functionality to the +** xTimerReset() API function. +** Starting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n 'ticks after xTimerStart() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerStart() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerStart() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStart() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the start command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStart() was called. +** xBlockTime is ignored if xTimerStart() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerStart() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStop(xTimer, xBlockTime) \ + xTimerStop(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerStop (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerStop() stops a timer that was previously started using +** either of the xTimerStart(), xTimerReset(), +** xTimerStartFromISR(), xTimerResetFromISR(), +** xTimerChangePeriod() and xTimerChangePeriodFromISR() API +** functions. +** Stopping a timer ensures the timer is not in the active +** state. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerStop() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the stop command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerStop() was called. +** xBlockTime is ignored if xTimerStop() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) \ + xTimerChangePeriod(xTimer, xNewPeriod, xBlockTime) +/* +** =================================================================== +** Method : xTimerChangePeriod (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerChangePeriod() changes the period of a timer that was +** previously created using the xTimerCreate() API function. +** xTimerChangePeriod() can be called to change the period of +** an active or dormant state timer. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerChangePeriod() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the change period +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerChangePeriod() +** was called. xBlockTime is ignored if +** xTimerChangePeriod() is called before the +** RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the change +** period command could not be sent to the +** timer command queue even after xBlockTime +** ticks had passed. pdPASS will be returned +** if the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerDelete(xTimer, xBlockTime) \ + xTimerDelete(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerDelete (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerDelete() deletes a timer that was previously created +** using the xTimerCreate() API function. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerDelete() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** deleted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the delete +** command to be successfully sent to the +** timer command queue, should the queue +** already be full when xTimerDelete() was +** called. xBlockTime is ignored if +** xTimerDelete() is called before the RTOS +** scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the delete +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerReset(xTimer, xBlockTime) \ + xTimerReset(xTimer, xBlockTime) +/* +** =================================================================== +** Method : xTimerReset (component FreeRTOS) +** +** Description : +** Timer functionality is provided by a timer service/daemon +** task. Many of the public FreeRTOS timer API functions send +** commands to the timer service task through a queue called +** the timer command queue. The timer command queue is private +** to the RTOS kernel itself and is not directly accessible to +** application code. The length of the timer command queue is +** set by the configTIMER_QUEUE_LENGTH configuration constant. +** xTimerReset() re-starts a timer that was previously created +** using the xTimerCreate() API function. If the timer had +** already been started and was already in the active state, +** then xTimerReset() will cause the timer to re-evaluate its +** expiry time so that it is relative to when xTimerReset() was +** called. If the timer was in the dormant state then +** xTimerReset() has equivalent functionality to the +** xTimerStart() API function. +** Resetting a timer ensures the timer is in the active state. +** If the timer is not stopped, deleted, or reset in the mean +** time, the callback function associated with the timer will +** get called 'n' ticks after xTimerReset() was called, where +** 'n' is the timers defined period. +** It is valid to call xTimerReset() before the RTOS scheduler +** has been started, but when this is done the timer will not +** actually start until the RTOS scheduler is started, and the +** timers expiry time will be relative to when the RTOS +** scheduler is started, not relative to when xTimerReset() was +** called. +** The configUSE_TIMERS configuration constant must be set to 1 +** for xTimerReset() to be available. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** reset/started/restarted. +** xBlockTime - Specifies the time, in ticks, +** that the calling task should be held in the +** Blocked state to wait for the reset command +** to be successfully sent to the timer +** command queue, should the queue already be +** full when xTimerReset() was called. +** xBlockTime is ignored if xTimerReset() is +** called before the RTOS scheduler is started. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue even after xBlockTime ticks +** had passed. pdPASS will be returned if the +** command was successfully sent to the timer +** command queue. When the command is actually +** processed will depend on the priority of +** the timer service/daemon task relative to +** other tasks in the system, although the +** timers expiry time is relative to when +** xTimerReset() is actually called. The timer +** service/daemon task priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStartFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStartFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStart() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** started/restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStartFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStartFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStartFromISR() function. If +** xTimerStartFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the start +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerStartFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerStopFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerStopFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerStop() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** stopped. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerStopFromISR() writes a +** message to the timer command queue, so has +** the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerStopFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerStopFromISR() function. If +** xTimerStopFromISR() sets this value to +** pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the stop +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system. The +** timer service/daemon task priority is set +** by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) \ + xTimerChangePeriodFromISR(xTimer, xNewPeriod, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerChangePeriodFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerChangePeriod() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is +** having its period changed. +** xNewPeriod - The new period for xTimer. +** Timer periods are specified in tick periods, +** so the constant portTICK_PERIOD_MS can be +** used to convert a time that has been +** specified in milliseconds. For example, if +** the timer must expire after 100 ticks, then +** xNewPeriod should be set to 100. +** Alternatively, if the timer must expire +** after 500ms, then xNewPeriod can be set to +** ( 500 / portTICK_PERIOD_MS ) provided +** configTICK_RATE_HZ is less than or equal to +** 1000. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerChangePeriodFromISR() +** writes a message to the timer command queue, +** so has the potential to transition the +** timer service/ daemon task out of the +** Blocked state. If calling +** xTimerChangePeriodFromISR() causes the +** timer service/daemon task to leave the +** Blocked state, and the timer service/daemon +** task has a priority equal to or greater +** than the currently executing task (the task +** that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerChangePeriodFromISR() function. If +** xTimerChangePeriodFromISR() sets this value +** to pdTRUE, then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the command to +** change the timers period could not be sent +** to the timer command queue. pdPASS will be +** returned if the command was successfully +** sent to the timer command queue. When the +** command is actually processed will depend +** on the priority of the timer service/daemon +** task relative to other tasks in the system. +** The timer service/daemon task priority is +** set by the configTIMER_TASK_PRIORITY +** configuration constant. +** =================================================================== +*/ + +#define FRTOS1_xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) \ + xTimerResetFromISR(xTimer, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerResetFromISR (component FreeRTOS) +** +** Description : +** A version of xTimerReset() that can be called from an +** interrupt service routine. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer that is to +** be started, reset, or restarted. +** * pxHigherPriorityTaskWoken +** - The timer service/daemon task spends most +** of its time in the Blocked state, waiting +** for messages to arrive on the timer command +** queue. Calling xTimerResetFromISR() writes +** a message to the timer command queue, so +** has the potential to transition the timer +** service/daemon task out of the Blocked +** state. If calling xTimerResetFromISR() +** causes the timer service/daemon task to +** leave the Blocked state, and the timer +** service/ daemon task has a priority equal +** to or greater than the currently executing +** task (the task that was interrupted), then +** *pxHigherPriorityTaskWoken will get set to +** pdTRUE internally within the +** xTimerResetFromISR() function. If +** xTimerResetFromISR() sets this value to +** pdTRUE then a context switch should be +** performed before the interrupt exits. +** Returns : +** --- - pdFAIL will be returned if the reset +** command could not be sent to the timer +** command queue. pdPASS will be returned if +** the command was successfully sent to the +** timer command queue. When the command is +** actually processed will depend on the +** priority of the timer service/daemon task +** relative to other tasks in the system, +** although the timers expiry time is relative +** to when xTimerResetFromISR() is actually +** called. The timer service/daemon task +** priority is set by the +** configTIMER_TASK_PRIORITY configuration +** constant. +** =================================================================== +*/ + +#define FRTOS1_pvTimerGetTimerID(xTimer) \ + pvTimerGetTimerID(xTimer) +/* +** =================================================================== +** Method : pvTimerGetTimerID (component FreeRTOS) +** +** Description : +** Returns the ID assigned to the timer. +** IDs are assigned to timers using the pvTimerID parameter of +** the call to xTimerCreate() that was used to create the timer. +** If the same callback function is assigned to multiple timers +** then the timer ID can be used within the callback function +** to identify which timer actually expired. +** Parameters : +** NAME - DESCRIPTION +** xTimer - The timer being queried. +** Returns : +** --- - The ID assigned to the timer being queried. +** =================================================================== +*/ + +#define FRTOS1_xTimerGetTimerDaemonTaskHandle() \ + xTimerGetTimerDaemonTaskHandle() +/* +** =================================================================== +** Method : xTimerGetTimerDaemonTaskHandle (component FreeRTOS) +** +** Description : +** INCLUDE_xTimerGetTimerDaemonTaskHandle and configUSE_TIMERS +** must both be set to 1 in FreeRTOSConfig.h for +** xTimerGetTimerDaemonTaskHandle() to be available. +** Parameters : None +** Returns : +** --- - Returns the task handle associated with +** the software timer daemon (or service) task. +** If configUSE_TIMERS is set to 1 in +** FreeRTOSConfig.h, then the timer daemon +** task is created automatically when the RTOS +** scheduler is started. +** =================================================================== +*/ + +#define FRTOS1_pcTimerGetTimerName(xTimer) \ + pcTimerGetTimerName(xTimer) +/* +** =================================================================== +** Method : pcTimerGetTimerName (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xTimer - The handle of the timer being +** queried. +** Returns : +** --- - A pointer to the timer's name, which is a +** standard NULL terminated C string. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) \ + xTimerPendFunctionCall(xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait) +/* +** =================================================================== +** Method : xTimerPendFunctionCall (component FreeRTOS) +** +** Description : +** Used to pend the execution of a function to the RTOS daemon +** task (the timer service task, hence this function is +** pre-fixed with 'Timer'). +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCall() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** xTicksToWait - Calling this function +** will result in a message being sent to the +** timer daemon task on a queue. xTicksToWait +** is the amount of time the calling task +** should remain in the Blocked state (so not +** using any processing time) for space to +** become available on the timer queue if the +** queue is found to be full. The length of +** the queue is set by the value of +** configTIMER_QUEUE_LENGTH in FreeRTOSConfig. +** h. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) \ + xTimerPendFunctionCallFromISR(xFunctionToPend, pvParameter1, ulParameter2, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTimerPendFunctionCallFromISR (component FreeRTOS) +** +** Description : +** Used from application interrupt service routines to defer +** the execution of a function to the RTOS daemon task (the +** timer service task, hence this function is implemented in +** timers.c and is prefixed with 'Timer'). +** Ideally an interrupt service routine (ISR) is kept as short +** as possible, but sometimes an ISR either has a lot of +** processing to do, or needs to perform processing that is not +** deterministic. In these cases xTimerPendFunctionCallFromISR() +** can be used to defer processing of a function to the RTOS +** daemon task. +** A mechanism is provided that allows the interrupt to return +** directly to the task that will subsequently execute the +** pended function. This allows the callback function to +** execute contiguously in time with the interrupt - just as if +** the callback had executed in the interrupt itself. +** Functions that can be deferred to the RTOS daemon task must +** have the following prototype: +** void vPendableFunction( void * pvParameter1, uint32_t +** ulParameter2 ); +** The pvParameter1 and ulParameter2 are provided for use by +** the application code. +** INCLUDE_xTimerPendFunctionCall() and configUSE_TIMERS must +** both be set to 1 for xTimerPendFunctionCallFromISR() to be +** available. +** Parameters : +** NAME - DESCRIPTION +** xFunctionToPend - The function to +** execute from the timer service/ daemon task. +** The function must conform to the +** PendedFunction_t prototype as shown above. +** * pvParameter1 - The value of the +** callback function's first parameter. The +** parameter has a void * type to allow it to +** be used to pass any type. For example, +** integer types can be cast to a void *, or +** the void * can be used to point to a +** structure. +** ulParameter2 - The value of the +** callback function's second parameter. +** * pxHigherPriorityTaskWoken +** - As mentioned above, calling +** xTimerPendFunctionCallFromISR() will result +** in a message being sent to the RTOS timer +** daemon task. If the priority of the daemon +** task (which is set using +** configTIMER_TASK_PRIORITY in FreeRTOSConfig. +** h) is higher than the priority of the +** currently running task (the task the +** interrupt interrupted) then +** *pxHigherPriorityTaskWoken will be set to +** pdTRUE within +** xTimerPendFunctionCallFromISR(), indicating +** that a context switch should be requested +** before the interrupt exits. For that reason +** *pxHigherPriorityTaskWoken must be +** initialised to pdFALSE. See the example +** code below. +** Returns : +** --- - pdPASS is returned if the message was +** successfully sent to the RTOS timer daemon +** task, otherwise pdFALSE is returned. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyGive(xTaskToNotify) \ + xTaskNotifyGive(xTaskToNotify) \ +/* +** =================================================================== +** Method : xTaskNotifyGive (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** xTaskNotifyGive() is a macro intended for use when an RTOS +** task notification value is being used as a light weight and +** faster binary or counting semaphore alternative. FreeRTOS +** semaphores are given using the xSemaphoreGive() API function, +** xTaskNotifyGive() is the equivalent that instead uses the +** receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** xTaskNotifyGive() must not be called from an interrupt +** service routine. Use vTaskNotifyGiveFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** Returns : +** --- - xTaskNotifyGive() is a macro that calls +** xTaskNotify() with the eAction parameter +** set to eIncrement resulting in all calls +** returning pdPASS. +** =================================================================== +*/ + +#define FRTOS1_ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) \ + ulTaskNotifyTake(xClearCountOnExit, xTicksToWait) +/* +** =================================================================== +** Method : ulTaskNotifyTake (component FreeRTOS) +** +** Description : +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** ulTaskNotifyTake() is intended for use when a task +** notification is used as a faster and lighter weight binary +** or counting semaphore alternative. FreeRTOS semaphores are +** taken using the xSemaphoreTake() API function, +** ulTaskNotifyTake() is the equivalent that instead uses a +** task notification. +** When a task is using its notification value as a binary or +** counting semaphore other tasks and interrupts should send +** notifications to it using either the xTaskNotifyGive() macro, +** or the xTaskNotify() function with the function's eAction +** parameter set to eIncrement (the two are equivalent). +** ulTaskNotifyTake() can either clear the task's notification +** value to zero on exit, in which case the notification value +** acts like a binary semaphore, or decrement the task's +** notification value on exit, in which case the notification +** value acts more like a counting semaphore. +** An RTOS task can use ulTaskNotifyTake() to [optionally] +** block to wait for a the task's notification value to be +** non-zero. The task does not consume any CPU time while it is +** in the Blocked state. +** Where as xTaskNotifyWait() will return when a notification +** is pending, ulTaskNotifyTake() will return when the task's +** notification value is not zero, decrementing the task's +** notification value before it returns. +** Parameters : +** NAME - DESCRIPTION +** xClearCountOnExit - If an RTOS +** task notification is received and +** xClearCountOnExit is set to pdFALSE then +** the RTOS task's notification value is +** decremented before ulTaskNotifyTake() exits. +** This is equivalent to the value of a +** counting semaphore being decremented by a +** successful call to xSemaphoreTake(). +** If an RTOS task notification is received +** and xClearCountOnExit is set to pdTRUE then +** the RTOS task's notification value is reset +** to 0 before ulTaskNotifyTake() exits. This +** is equivalent to the value of a binary +** semaphore being left at zero (or empty, or +** 'not available') after a successful call to +** xSemaphoreTake(). +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when ulTaskNotifyTake() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - The value of the task's notification value +** before it is decremented or cleared (see +** the description of xClearCountOnExit). +** =================================================================== +*/ + +#define FRTOS1_vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) \ + vTaskNotifyGiveFromISR(xTaskToNotify, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : vTaskNotifyGiveFromISR (component FreeRTOS) +** +** Description : +** A version of xTaskNotifyGive() that can be called from an +** interrupt service routine (ISR). +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value. +** vTaskNotifyGiveFromISR() is a function intended for use when +** an RTOS task notification value is being used as a light +** weight and faster binary or counting semaphore alternative. +** FreeRTOS semaphores are given from an interrupt using the +** xSemaphoreGiveFromISR() API function, +** vTaskNotifyGiveFromISR() is the equivalent that instead uses +** the receiving RTOS task's notification value. +** When a task notification value is being used as a binary or +** counting semaphore equivalent then the task being notified +** should wait for the notification using the ulTaskNotifyTake() +** API function rather than the xTaskNotifyWait() API function. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified, and having its +** notification value incremented. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** vTaskNotifyGiveFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If vTaskNotifyGiveFromISR() sets this value +** to pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskNotify(xTaskToNotify, ulValue, eAction) \ + xTaskNotify(xTaskToNotify, ulValue, eAction) +/* +** =================================================================== +** Method : xTaskNotify (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) \ + xTaskNotifyFromISR(xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** A version of xTaskNotify() that can be called from an ISR. +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** - eNoAction: The subject task receives the +** event, but its notification value is not +** updated. In this case ulValue is not used. +** - eSetBits: The notification value of the +** subject task will be bitwise ORed with +** ulValue. For example, if ulValue is set to +** 0x01, then bit 0 will get set within the +** subject task's notification value. Likewise +** if ulValue is 0x04 then bit 2 will get set +** in the subject task's notification value. +** In this way the RTOS task notification +** mechanism can be used as a light weight +** alternative to an event group. +** - eIncrement: The notification value of +** the subject task will be incremented by one, +** making the call to xTaskNotify() equivalent +** to a call to xTaskNotifyGive(). In this +** case ulValue is not used. +** - eSetValueWithOverwrite: The notification +** value of the subject task is +** unconditionally set to ulValue. In this way +** the RTOS task notification mechanism is +** being used as a light weight alternative to +** xQueueOverwrite(). +** - eSetValueWithoutOverwrite: If the +** subject task does not already have a +** notification pending then its notification +** value will be set to ulValue. If the +** subject task already has a notification +** pending then its notification value is not +** updated as to do so would overwrite the +** previous value before it was used. In this +** case the call to xTaskNotify() fails and +** pdFALSE is returned. In this way the RTOS +** task notification mechanism is being used +** as a light weight alternative to +** xQueueSend() on a queue of length 1. +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) \ + xTaskNotifyWait(ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait) +/* +** =================================================================== +** Method : xTaskNotifyWait (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler ulTaskNotifyTake() API function instead of +** xTaskNotifyWait()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. An RTOS +** task notification is an event sent directly to a task that +** can unblock the receiving task, and optionally update the +** receiving task's notification value in a number of different +** ways. For example, a notification may overwrite the +** receiving task's notification value, or just set one or more +** bits in the receiving task's notification value. See the +** RTOS task notifications use case documentation for examples. +** xTaskNotifyWait() waits, with an optional timeout, for the +** calling task to receive a notification. +** If the receiving RTOS task was already Blocked waiting for a +** notification when one arrives the receiving RTOS task will +** be removed from the Blocked state and the notification +** cleared. +** Parameters : +** NAME - DESCRIPTION +** ulBitsToClearOnEntry - Any bits +** set in ulBitsToClearOnEntry will be cleared +** in the calling RTOS task's notification +** value on entry to the xTaskNotifyWait() +** function (before the task waits for a new +** notification) provided a notification is +** not already pending when xTaskNotifyWait() +** is called. +** For example, if ulBitsToClearOnEntry is +** 0x01, then bit 0 of the task's notification +** value will be cleared on entry to the +** function. +** Setting ulBitsToClearOnEntry to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** ulBitsToClearOnExit - Any bits +** set in ulBitsToClearOnExit will be cleared +** in the calling RTOS task's notification +** value before xTaskNotifyWait() function +** exits if a notification was received. +** The bits are cleared after the RTOS task's +** notification value has been saved in +** *pulNotificationValue (see the description +** of pulNotificationValue below). +** For example, if ulBitsToClearOnExit is 0x03, +** then bit 0 and bit 1 of the task's +** notification value will be cleared before +** the function exits. +** Setting ulBitsToClearOnExit to 0xffffffff +** (ULONG_MAX) will clear all the bits in the +** task's notification value, effectively +** clearing the value to 0. +** * pulNotificationValue - Used to +** pass out the RTOS task's notification value. +** The value copied to *pulNotificationValue +** is the RTOS task's notification value as it +** was before any bits were cleared due to the +** ulBitsToClearOnExit setting. +** If the notification value is not required +** then set pulNotificationValue to NULL. +** xTicksToWait - The maximum time to wait +** in the Blocked state for a notification to +** be received if a notification is not +** already pending when xTaskNotifyWait() is +** called. +** The RTOS task does not consume any CPU time +** when it is in the Blocked state. +** The time is specified in RTOS tick periods. +** The pdMS_TO_TICKS() macro can be used to +** convert a time specified in milliseconds +** into a time specified in ticks. +** Returns : +** --- - pdTRUE if a notification was received, or +** a notification was already pending when +** xTaskNotifyWait() was called. +** pdFALSE if the call to xTaskNotifyWait() +** timed out before a notification was +** received. +** =================================================================== +*/ + +#define FRTOS1_vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) \ + vTaskSetThreadLocalStoragePointer(xTaskToSet, xIndex, pvValue) +/* +** =================================================================== +** Method : vTaskSetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Only enabled if configNUM_THREAD_LOCAL_STORAGE_POINTERS is > +** 0. +** Parameters : +** NAME - DESCRIPTION +** xTaskToSet - Task handle +** xIndex - Index of thread local storage item +** pvValue - +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) \ + pvTaskGetThreadLocalStoragePointer(xTaskToQuery, xIndex) +/* +** =================================================================== +** Method : pvTaskGetThreadLocalStoragePointer (component FreeRTOS) +** +** Description : +** Sets the thread local storage. Only enabled if +** configNUM_THREAD_LOCAL_STORAGE_POINTERS is >0 +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - Task handle from which +** to get the local thread storage. +** xIndex - Index of thread storage +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinary() \ + xSemaphoreCreateBinary() +/* +** =================================================================== +** Method : xSemaphoreCreateBinary (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : None +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) \ + xTaskNotifyAndQuery(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue) +/* +** =================================================================== +** Method : xTaskNotifyAndQuery (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) \ + xTaskNotifyAndQueryFromISR(xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue, pxHigherPriorityTaskWoken) +/* +** =================================================================== +** Method : xTaskNotifyAndQueryFromISR (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** Each RTOS task has a 32-bit notification value which is +** initialised to zero when the RTOS task is created. +** xTaskNotify() is used to send an event directly to and +** potentially unblock an RTOS task, and optionally update the +** receiving task's notification value in one of the following +** ways: +** - Write a 32-bit number to the notification value +** - Add one (increment) the notification value +** - Set one or more bits in the notification value +** - Leave the notification value unchanged +** This function must not be called from an interrupt service +** routine (ISR). Use xTaskNotifyFromISR() instead. +** Parameters : +** NAME - DESCRIPTION +** xTaskToNotify - The handle of the RTOS +** task being notified. This is the subject +** task. +** RTOS task handles are obtained using the +** pvCreatedTask parameter of the xTaskCreate() +** call used to create the task. +** The handle of the currently executing RTOS +** task is returned by the +** xTaskGetCurrentTaskHandle() API function. +** ulValue - Used to update the notification +** value of the subject task. See the +** description of the eAction parameter below. +** eAction - An enumerated type that can take +** one of the values documented in the table +** below in order to perform the associated +** action. +** * pulPreviousNotifyValue - Can +** be used to pass out the subject task's +** notification value before any bits are +** modified by the action of +** xTaskNotifyAndQuery(). +** pulPreviousNotifyValue is an optional +** parameter, and can be set to NULL if it is +** not required. If pulPreviousNotifyValue is +** not used then consider using xTaskNotify() +** in place of xTaskNotifyAndQuery(). +** * pxHigherPriorityTaskWoken +** - *pxHigherPriorityTaskWoken must be +** initialised to 0. +** xTaskNotifyFromISR() will set +** *pxHigherPriorityTaskWoken to pdTRUE if +** sending the notification caused a task to +** unblock, and the unblocked task has a +** priority higher than the currently running +** task. +** If xTaskNotifyFromISR() sets this value to +** pdTRUE then a context switch should be +** requested before the interrupt is exited. +** See the example below. +** pxHigherPriorityTaskWoken is an optional +** parameter and can be set to NULL. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +#define FRTOS1_xTaskNotifyStateClear(xTask) \ + xTaskNotifyStateClear(xTask) +/* +** =================================================================== +** Method : xTaskNotifyStateClear (component FreeRTOS) +** +** Description : +** [If you are using RTOS task notifications to implement +** binary or counting semaphore type behaviour then use the +** simpler xTaskNotifyGive() API function instead of +** xTaskNotify()] +** If the notification state of the task referenced by the +** handle xTask is eNotified, then set the task's notification +** state to eNotWaitingNotification. The task's notification +** value is not altered. Set xTask to NULL to clear the +** notification state of the calling task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the RTOS task. Use NULL +** for using the calling task. +** Returns : +** --- - pdPASS is returned in all cases other than +** when eAction is set to +** eSetValueWithoutOverwrite and the subject +** task's notification value cannot be updated +** because the subject task already had a +** notification pending. +** =================================================================== +*/ + +void FRTOS1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component FreeRTOS) +** +** Description : +** Module deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_xTaskGetHandle(pcNameToQuery) \ + xTaskGetHandle(pcNameToQuery) + +/* +** =================================================================== +** Method : xTaskGetHandle (component FreeRTOS) +** +** Description : +** Looks up the handle of a task from the task's name. +** Parameters : +** NAME - DESCRIPTION +** * pcNameToQuery - The text name (as a +** standard C NULL terminated string) of the +** task for which the handle will be returned. +** Returns : +** --- - If a task that has the name passed in +** pcNameToQuery can be located then the +** handle of the task is returned, otherwise +** NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_pcTaskGetName(xTaskToQuery) \ + pcTaskGetName(xTaskToQuery) + +/* +** =================================================================== +** Method : pcTaskGetName (component FreeRTOS) +** +** Description : +** Looks up the name of a task from the task's handle. +** Parameters : +** NAME - DESCRIPTION +** xTaskToQuery - The handle of the task +** being queried. xTaskToQuery can be set to +** NULL to query the name of the calling task. +** Returns : +** --- - A pointer to the subject task's name, +** which is a standard NULL terminated C +** string. +** =================================================================== +*/ + +#define FRTOS1_xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) \ + xTaskCreateStatic(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer) + +/* +** =================================================================== +** Method : xTaskCreateStatic (component FreeRTOS) +** +** Description : +** Create a new task and add it to the list of tasks that are +** ready to run. +** Parameters : +** NAME - DESCRIPTION +** pvTaskCode - Pointer to the task entry +** function. Tasks must be implemented to +** never return (i.e. continuous loop). +** pcName - A descriptive name for the task. +** This is mainly used to facilitate debugging. +** Max length defined by +** configMAX_TASK_NAME_LEN. +** usStackDepth - The size of the task +** stack specified as the number of variables +** the stack can hold - not the number of +** bytes. For example, if the stack is 16 bits +** wide and usStackDepth is defined as 100, +** 200 bytes will be allocated for stack +** storage. The stack depth multiplied by the +** stack width must not exceed the maximum +** value that can be contained in a variable +** of type size_t. +** pvParameters - Pointer that will be +** used as the parameter for the task being +** created. +** uxPriority - The priority at which the +** task should run. +** puxStackBuffer - Must point to a +** StackType_t array that has at least +** ulStackDepth indexes (see the ulStackDepth +** parameter above) - the array will be used +** as the task's stack, so must be persistent +** (not declared on the stack of a function) +** pxTaskBuffer - Must point to a variable +** of type StaticTask_t. The variable will be +** used to hold the new task's data structures +** (TCB), so it must be persistent (not +** declared on the stack of a function). +** Returns : +** --- - Task handle if the task was successfully +** created and added to a ready list, +** otherwise Null. +** =================================================================== +*/ + +#define FRTOS1_xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) \ + xQueueCreateStatic(uxQueueLength, uxItemSize, pucQueueStorageBuffer, pxQueueBuffer) + +/* +** =================================================================== +** Method : xQueueCreateStatic (component FreeRTOS) +** +** Description : +** Creates a queue. +** Parameters : +** NAME - DESCRIPTION +** uxQueueLength - The maximum number of +** items the queue can hold at any time. +** uxItemSize - The size in bytes of each +** item the queue will hold. +** pucQueueStorageBuffer - If +** uxItemSize is not zero then +** pucQueueStorageBuffer must point to a +** uint8_t array that is at least large enough +** to hold the maximum number of items that +** can be in the queue at any one time - which +** is ( uxQueueLength * uxItemSize ) bytes. If +** uxItemSize is zero then +** pucQueueStorageBuffer can be NULL. +** pxQueueBuffer - Must point to a +** variable of type StaticQueue_t, which will +** be used to hold the queue's data structure. +** Returns : +** --- - A handle to the created queue is returned +** provided the queue was created successfully. +** NULL is returned if the queue cannot be +** created because there is too little heap +** RAM available. +** =================================================================== +*/ + +#define FRTOS1_xEventGroupCreateStatic(pxEventGroupBuffer) \ + xEventGroupCreateStatic(pxEventGroupBuffer) + +/* +** =================================================================== +** Method : xEventGroupCreateStatic (component FreeRTOS) +** +** Description : +** Create a new RTOS event group. This function cannot be +** called from an interrupt. +** Event groups are stored in variables of type +** EventGroupHandle_t. The number of bits (or flags) +** implemented within an event group is 8 if +** configUSE_16_BIT_TICKS is set to 1, or 24 if +** configUSE_16_BIT_TICKS is set to 0. The dependency on +** configUSE_16_BIT_TICKS results from the data type used for +** thread local storage in the internal implementation of RTOS +** tasks. +** Parameters : +** NAME - DESCRIPTION +** pxEventGroupBuffer - Must point +** to a variable of type StaticEventGroup_t, +** in which the event group data structure +** will be stored. +** Returns : +** --- - Event Group Handle. If the event group was +** created then a handle to the event group is +** returned. If there was insufficient +** FreeRTOS heap available to create the event +** group then NULL is returned. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) \ + xSemaphoreCreateBinaryStatic(pxSemaphoreBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateBinaryStatic (component FreeRTOS) +** +** Description : +** The old vSemaphoreCreateBinary() macro is now deprecated in +** favour of this xSemaphoreCreateBinary() function. Note that +** binary semaphores created using the vSemaphoreCreateBinary() +** macro are created in a state such that the first call to +** 'take' the semaphore would pass, whereas binary semaphores +** created using xSemaphoreCreateBinary() are created in a +** state such that the the semaphore must first be 'given' +** before it can be 'taken'. +** Function that creates a semaphore by using the existing +** queue mechanism. The queue length is 1 as this is a binary +** semaphore. The data size is 0 as nothing is actually stored +** - all that is important is whether the queue is empty or +** full (the binary semaphore is available or not). +** This type of semaphore can be used for pure synchronisation +** between tasks or between an interrupt and a task. The +** semaphore need not be given back once obtained, so one +** task/interrupt can continuously 'give' the semaphore while +** another continuously 'takes' the semaphore. For this reason +** this type of semaphore does not use a priority inheritance +** mechanism. For an alternative that does use priority +** inheritance see xSemaphoreCreateMutex(). +** Parameters : +** NAME - DESCRIPTION +** pxSemaphoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** will be used to hold the semaphore's state. +** Returns : +** --- - Handle to the created semaphore. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) \ + xSemaphoreCreateCountingStatic(uxMaxCount, uxInitialCount, pxSempahoreBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateCountingStatic (component FreeRTOS) +** +** Description : +** Macro that creates a counting semaphore by using the +** existing queue mechanism. +** Counting semaphores are typically used for two things: +** 1. Counting events. +** In this usage scenario an event handler will 'give' a +** semaphore each time an event occurs (incrementing the +** semaphore count value), and a handler task will 'take' a +** semaphore each time it processes an event (decrementing the +** semaphore count value). The count value is therefore the +** difference between the number of events that have occurred +** and the number that have been processed. In this case it is +** desirable for the initial count value to be zero. +** 2. Resource management. +** In this usage scenario the count value indicates the number +** of resources available. To obtain control of a resource a +** task must first obtain a semaphore - decrementing the +** semaphore count value. When the count value reaches zero +** there are no free resources. When a task finishes with the +** resource it 'gives' the semaphore back - incrementing the +** semaphore count value. In this case it is desirable for the +** initial count value to be equal to the maximum count value, +** indicating that all resources are free. +** Parameters : +** NAME - DESCRIPTION +** uxMaxCount - The maximum count value that +** can be reached. When the semaphore reaches +** this value it can no longer be 'given'. +** uxInitialCount - The count value +** assigned to the semaphore when it is +** created. +** pxSempahoreBuffer - Must point to +** a variable of type StaticSemaphore_t, which +** is then used to hold the semaphore's data +** structures. +** Returns : +** --- - xSemaphoreHandle handle +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateMutexStatic(pxMutexBuffer) + +/* +** =================================================================== +** Method : xSemaphoreCreateMutexStatic (component FreeRTOS) +** +** Description : +** Macro that creates a mutex semaphore by using the existing +** queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTake() and xSemaphoreGive() macros. The +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros should not be used. +** Mutexes and binary semaphores are very similar but have some +** subtle differences: Mutexes include a priority inheritance +** mechanism, binary semaphores do not. This makes binary +** semaphores the better choice for implementing +** synchronisation (between tasks or between tasks and an +** interrupt), and mutexes the better choice for implementing +** simple mutual exclusion. +** The priority of a task that 'takes' a mutex can potentially +** be raised if another task of higher priority attempts to +** obtain the same mutex. The task that owns the mutex +** 'inherits' the priority of the task attempting to 'take' the +** same mutex. This means the mutex must always be 'given' back +** - otherwise the higher priority task will never be able to +** obtain the mutex, and the lower priority task will never +** 'disinherit' the priority. An example of a mutex being used +** to implement mutual exclusion is provided on the +** xSemaphoreTake() documentation page. +** A binary semaphore need not be given back once obtained, so +** task synchronisation can be implemented by one +** task/interrupt continuously 'giving' the semaphore while +** another continuously 'takes' the semaphore. This is +** demonstrated by the sample code on the +** xSemaphoreGiveFromISR() documentation page. +** Both mutex and binary semaphores are assigned to variables +** of type xSemaphoreHandle and can be used in any API function +** that takes a parameter of this type. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +#define FRTOS1_vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) \ + vTaskGetInfo(xTask, pxTaskStatus, xGetFreeStackSpace, eState) +/* +** =================================================================== +** Method : vTaskGetInfo (component FreeRTOS) +** +** Description : +** Whereas uxTaskGetSystemState() populates a TaskStatus_t +** structure for each task in the system, vTaskGetInfo() +** populates a TaskStatus_t structures for just a single task. +** The TaskStatus_t structure contains, among other things, +** members for the task handle, task name, task priority, task +** state, and total amount of run time consumed by the task. +** Parameters : +** NAME - DESCRIPTION +** xTask - The handle of the task being queried. +** Setting xTask to NULL will return +** information on the calling task. +** pxTaskStatus - The TaskStatus_t +** structure pointed to by pxTaskStatus will +** be filled with information about the task +** referenced by the handle passed in the +** xTask parameter. +** xGetFreeStackSpace - The +** TaskStatus_t structure contains a member to +** report the stack high water mark of the +** task being queried. The stack high water +** mark is the minimum amount of stack space +** that has ever existed, so the closer the +** number is to zero the closer the task has +** come to overflowing its stack.Calculating +** the stack high water mark takes a +** relatively long time, and can make the +** system temporarily unresponsive - so the +** xGetFreeStackSpace parameter is provided to +** allow the high water mark checking to be +** skipped. The high watermark value will only +** be written to the TaskStatus_t structure if +** xGetFreeStackSpace is not set to pdFALSE. +** eState - The TaskStatus_t structure contains +** a member to report the state of the task +** being queried. Obtaining the task state is +** not as fast as a simple assignment - so the +** eState parameter is provided to allow the +** state information to be omitted from the +** TaskStatus_t structure. To obtain state +** information then set eState to eInvalid - +** otherwise the value passed in eState will +** be reported as the task state in the +** TaskStatus_t structure. +** Returns : Nothing +** =================================================================== +*/ + +#define FRTOS1_uxSemaphoreGetCount(xSemaphore) \ + uxSemaphoreGetCount(xSemaphore) +/* +** =================================================================== +** Method : uxSemaphoreGetCount (component FreeRTOS) +** +** Description : +** +** Parameters : +** NAME - DESCRIPTION +** xSemaphore - The handle of the semaphore +** being queried. +** Returns : +** --- - If the semaphore is a counting semaphore +** then the semaphores current count value is +** returned. If the semaphore is a binary +** semaphore then 1 is returned if the +** semaphore is available, and 0 is returned +** if the semaphore is not available. +** =================================================================== +*/ + +#define FRTOS1_xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) \ + xSemaphoreCreateRecursiveMutexStatic(pxMutexBuffer) +/* +** =================================================================== +** Method : xSemaphoreCreateRecursiveMutexStatic (component FreeRTOS) +** +** Description : +** Macro that implements a recursive mutex by using the +** existing queue mechanism. +** Mutexes created using this macro can be accessed using the +** xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() +** macros. The xSemaphoreTake() and xSemaphoreGive() macros +** should not be used. +** A mutex used recursively can be 'taken' repeatedly by the +** owner. The mutex doesn't become available again until the +** owner has called xSemaphoreGiveRecursive() for each +** successful 'take' request. For example, if a task +** successfully 'takes' the same mutex 5 times then the mutex +** will not be available to any other task until it has also +** 'given' the mutex back exactly five times. +** This type of semaphore uses a priority inheritance mechanism +** so a task 'taking' a semaphore MUST ALWAYS 'give' the +** semaphore back once the semaphore it is no longer required. +** Mutex type semaphores cannot be used from within interrupt +** service routines. +** See vSemaphoreCreateBinary() for an alternative +** implementation that can be used for pure synchronisation +** (where one task or interrupt always 'gives' the semaphore +** and another always 'takes' the semaphore) and from within +** interrupt service routines. +** Parameters : +** NAME - DESCRIPTION +** Variable_1 - Must point to a variable of +** type StaticSemaphore_t, which will be used +** to hold the mutex type semaphore's state. +** Returns : +** --- - Handle to the created mutex semaphore. +** Should be of type xSemaphoreHandle. +** =================================================================== +*/ + +void FRTOS1_AppConfigureTimerForRuntimeStats(void); +/* +** =================================================================== +** Method : AppConfigureTimerForRuntimeStats (component FreeRTOS) +** +** Description : +** Configures the timer for generating runtime statistics +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +/* +** =================================================================== +** Method : AppGetRuntimeCounterValueFromISR (component FreeRTOS) +** +** Description : +** returns the current runtime counter. Function can be called +** from an interrupt service routine. +** Parameters : None +** Returns : +** --- - runtime counter value +** =================================================================== +*/ + +/* END FRTOS1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __FRTOS1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1config.h new file mode 100644 index 0000000..778c867 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FRTOS1config.h @@ -0,0 +1,155 @@ +#ifndef __FRTOS1_CONFIG_H +#define __FRTOS1_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ + +/* -------------------------------------------------------------------- */ +/* Macros to identify the compiler used: */ +#define configCOMPILER_ARM_GCC 1 /* GNU ARM gcc compiler */ +#define configCOMPILER_ARM_IAR 2 /* IAR ARM compiler */ +#define configCOMPILER_ARM_FSL 3 /* Legacy Freescale ARM compiler */ +#define configCOMPILER_ARM_KEIL 4 /* ARM/Keil compiler */ +#define configCOMPILER_S08_FSL 5 /* Freescale HCS08 compiler */ +#define configCOMPILER_S12_FSL 6 /* Freescale HCS12(X) compiler */ +#define configCOMPILER_CF1_FSL 7 /* Freescale ColdFire V1 compiler */ +#define configCOMPILER_CF2_FSL 8 /* Freescale ColdFire V2 compiler */ +#define configCOMPILER_DSC_FSL 9 /* Freescale DSC compiler */ + +#define configCOMPILER configCOMPILER_ARM_GCC +/* -------------------------------------------------------------------- */ +/* CPU family identification */ +#define configCPU_FAMILY_S08 1 /* S08 core */ +#define configCPU_FAMILY_S12 2 /* S12(X) core */ +#define configCPU_FAMILY_CF1 3 /* ColdFire V1 core */ +#define configCPU_FAMILY_CF2 4 /* ColdFire V2 core */ +#define configCPU_FAMILY_DSC 5 /* 56800/DSC */ +#define configCPU_FAMILY_ARM_M0P 6 /* ARM Cortex-M0+ */ +#define configCPU_FAMILY_ARM_M3 7 /* ARM Cortex-M3 */ +#define configCPU_FAMILY_ARM_M4 8 /* ARM Cortex-M4 */ +#define configCPU_FAMILY_ARM_M4F 9 /* ARM Cortex-M4F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M7 10 /* ARM Cortex-M7 */ +#define configCPU_FAMILY_ARM_M7F 11 /* ARM Cortex-M7F (with floating point unit) */ +#define configCPU_FAMILY_ARM_M33 12 /* ARM Cortex-M33 */ +#define configCPU_FAMILY_ARM_M33F 13 /* ARM Cortex-M33F (with floating point unit) */ +#define configCPU_FAMILY_RISC_V 14 /* RISC-V */ + +/* Macros to identify set of core families */ +#define configCPU_FAMILY_IS_ARM_M0(fam) ((fam)==configCPU_FAMILY_ARM_M0P) +#define configCPU_FAMILY_IS_ARM_M3(fam) ((fam)==configCPU_FAMILY_ARM_M3) +#define configCPU_FAMILY_IS_ARM_M4(fam) (((fam)==configCPU_FAMILY_ARM_M4) || ((fam)==configCPU_FAMILY_ARM_M4F)) +#define configCPU_FAMILY_IS_ARM_M7(fam) (((fam)==configCPU_FAMILY_ARM_M7) || ((fam)==configCPU_FAMILY_ARM_M7F)) +#define configCPU_FAMILY_IS_ARM_M4_M7(fam) (configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam)) +#define configCPU_FAMILY_IS_ARM_M33(fam) (((fam)==configCPU_FAMILY_ARM_M33) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM_FPU(fam) (((fam)==configCPU_FAMILY_ARM_M4F) || ((fam)==configCPU_FAMILY_ARM_M7F) || ((fam)==configCPU_FAMILY_ARM_M33F)) +#define configCPU_FAMILY_IS_ARM(fam) (configCPU_FAMILY_IS_ARM_M0(fam) || configCPU_FAMILY_IS_ARM_M4(fam) || configCPU_FAMILY_IS_ARM_M7(fam) || configCPU_FAMILY_IS_ARM_M33(fam)) + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* determine core based on library configuration */ + #if MCUC1_CONFIG_CORTEX_M==0 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M0P + #elif MCUC1_CONFIG_CORTEX_M==3 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M3 + #elif MCUC1_CONFIG_CORTEX_M==4 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4F + #elif MCUC1_CONFIG_CORTEX_M==4 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4 + #elif MCUC1_CONFIG_CORTEX_M==7 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7F + #elif MCUC1_CONFIG_CORTEX_M==7 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M7 + #elif MCUC1_CONFIG_CORTEX_M==33 && MCUC1_CONFIG_FPU_PRESENT + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33F + #elif MCUC1_CONFIG_CORTEX_M==33 + #define configCPU_FAMILY configCPU_FAMILY_ARM_M33 + #else + #error "unsupported configuaration!" + #endif +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configCPU_FAMILY configCPU_FAMILY_RISC_V +#else /* default CPU family */ + #define configCPU_FAMILY configCPU_FAMILY_ARM_M4 +#endif + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0 && (configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY)||configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY))) + /*!< 1: enable MPU support; 0: MPU support is disabled */ +#endif + +#ifndef configENABLE_FPU + #define configENABLE_FPU (1 && MCUC1_CONFIG_FPU_PRESENT) + /*!< 1: enable FPU support; 0: FPU support is disabled */ +#endif + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0 && configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) + /*!< 1: enable ARM TrustZone support; 0: TrustZone support is disabled */ +#endif + +/*----------------------------------------------------------- + * GDB backtrace handler support + * See http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + *----------------------------------------------------------*/ +#ifndef configGDB_HELPER + #define configGDB_HELPER (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GDB stack backtrace debug helper; 0: disabled */ +#endif + +#ifndef configLTO_HELPER + #define configLTO_HELPER (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC)) + /*!< 1: enable special GNU Link Time Optimizer (-lto) debug helper code; 0: disabled */ +#endif + +#ifndef configHEAP_SCHEME_IDENTIFICATION + #define configHEAP_SCHEME_IDENTIFICATION (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: use constant freeRTOSMemoryScheme to identify memory scheme; 0: no constant used */ +#endif + +#ifndef configUSE_TOP_USED_PRIORITY + #define configUSE_TOP_USED_PRIORITY (0 && configCPU_FAMILY_IS_ARM(configCPU_FAMILY)) + /*!< 1: Makes sure uxTopUsedPriority is present (needed for SEGGER and OpenOCD thread aware debugging); 0: no special reference to uxTopUsedPriority */ +#endif + +#ifndef configLINKER_HEAP_BASE_SYMBOL + #define configLINKER_HEAP_BASE_SYMBOL __HeapBase + /*!< Linker symbol used to denote the base address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapBase, MCUXpresso: _pvHeapStart) */ +#endif + +#ifndef configLINKER_HEAP_LIMIT_SYMBOL + #define configLINKER_HEAP_LIMIT_SYMBOL __HeapLimit + /*!< Linker symbol used to denote the limit address of the heap, used for heap memory scheme 6 (newlib). (KDS: __HeapLimit, MCUXpresso: _pvHeapLimit) */ +#endif + +#ifndef configLINKER_HEAP_SIZE_SYMBOL + #define configLINKER_HEAP_SIZE_SYMBOL __heap_size + /*!< Linker symbol used to denote the size of the heap, used for heap memory scheme 6 (newlib). (KDS: __heap_size, MCUXpresso: _HeapSize) */ +#endif + +#ifndef configUSE_SHELL + #define configUSE_SHELL (0) + /*!< 1: enable Shell and command line support; 0: disabled */ +#endif + +#ifndef configRESET_MSP + #define configRESET_MSP (1) + /*!< 1: reset MSP at scheduler start (Cortex M3/M4/M7 only); 0: do not reset MSP */ +#endif + + +/*----------------------------------------------------------- + * FreeRTOS Trace hook support + *----------------------------------------------------------- */ +#ifndef configUSE_PERCEPIO_TRACE_HOOKS + #define configUSE_PERCEPIO_TRACE_HOOKS 0 /* 1: Percepio Trace hooks, 0: not using Percepio Trace hooks */ +#endif +#define configUSE_TRACE_HOOKS configUSE_PERCEPIO_TRACE_HOOKS /* legacy configUSE_TRACE_HOOKS should not be used any more */ + +#ifndef configUSE_SEGGER_SYSTEM_VIEWER_HOOKS + #define configUSE_SEGGER_SYSTEM_VIEWER_HOOKS 0 /* 1: Segger System Viewer hooks, 0: not using Segger System Viewer hooks */ +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configUSE_PERCEPIO_TRACE_HOOKS + #error "only one trace method can be active!" +#endif +/*----------------------------------------------------------- */ + +#endif /* __FRTOS1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS.h new file mode 100644 index 0000000..ec88675 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS.h @@ -0,0 +1,1320 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef INC_FREERTOS_H +#define INC_FREERTOS_H + +/* + * Include the generic headers required for the FreeRTOS port being used. + */ +#include + +/* + * If stdint.h cannot be located then: + * + If using GCC ensure the -nostdint options is *not* being used. + * + Ensure the project's include path includes the directory in which your + * compiler stores stdint.h. + * + Set any compiler options necessary for it to support C99, as technically + * stdint.h is only mandatory with C99 (FreeRTOS does not require C99 in any + * other way). + * + The FreeRTOS download includes a simple stdint.h definition that can be + * used in cases where none is provided by the compiler. The files only + * contains the typedefs required to build FreeRTOS. Read the instructions + * in FreeRTOS/source/stdint.readme for more information. + */ +//#include /* READ COMMENT ABOVE. */ /*<< EST */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Application specific configuration options. */ +#include "FreeRTOSConfig.h" + +// #include /* READ COMMENT ABOVE. */ /* << EST */ +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "SIM_PDD.h" /*! \todo this is a PEx header */ +#endif + +/* Basic FreeRTOS definitions. */ +#include "projdefs.h" + +/* Definitions specific to the port being used. */ +#include "portable.h" + +/* Must be defaulted before configUSE_NEWLIB_REENTRANT is used below. */ +#ifndef configUSE_NEWLIB_REENTRANT + #define configUSE_NEWLIB_REENTRANT 0 +#endif + +/* Required if struct _reent is used. */ +#if ( configUSE_NEWLIB_REENTRANT == 1 ) + #include +#endif +/* + * Check all the required application specific macros have been defined. + * These macros are application specific and (as downloaded) are defined + * within FreeRTOSConfig.h. + */ + +#ifndef configMINIMAL_STACK_SIZE + #error Missing definition: configMINIMAL_STACK_SIZE must be defined in FreeRTOSConfig.h. configMINIMAL_STACK_SIZE defines the size (in words) of the stack allocated to the idle task. Refer to the demo project provided for your port for a suitable value. +#endif + +#ifndef configMAX_PRIORITIES + #error Missing definition: configMAX_PRIORITIES must be defined in FreeRTOSConfig.h. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#if configMAX_PRIORITIES < 1 + #error configMAX_PRIORITIES must be defined to be greater than or equal to 1. +#endif + +#ifndef configUSE_PREEMPTION + #error Missing definition: configUSE_PREEMPTION must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_IDLE_HOOK + #error Missing definition: configUSE_IDLE_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_TICK_HOOK + #error Missing definition: configUSE_TICK_HOOK must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_16_BIT_TICKS + #error Missing definition: configUSE_16_BIT_TICKS must be defined in FreeRTOSConfig.h as either 1 or 0. See the Configuration section of the FreeRTOS API documentation for details. +#endif + +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif + +#ifndef INCLUDE_vTaskPrioritySet + #define INCLUDE_vTaskPrioritySet 0 +#endif + +#ifndef INCLUDE_uxTaskPriorityGet + #define INCLUDE_uxTaskPriorityGet 0 +#endif + +#ifndef INCLUDE_vTaskDelete + #define INCLUDE_vTaskDelete 0 +#endif + +#ifndef INCLUDE_vTaskSuspend + #define INCLUDE_vTaskSuspend 0 +#endif + +#ifndef INCLUDE_vTaskDelayUntil + #define INCLUDE_vTaskDelayUntil 0 +#endif + +#ifndef INCLUDE_vTaskDelay + #define INCLUDE_vTaskDelay 0 +#endif + +#ifndef INCLUDE_xTaskGetIdleTaskHandle + #define INCLUDE_xTaskGetIdleTaskHandle 0 +#endif + +#ifndef INCLUDE_xTaskAbortDelay + #define INCLUDE_xTaskAbortDelay 0 +#endif + +#ifndef INCLUDE_xQueueGetMutexHolder + #define INCLUDE_xQueueGetMutexHolder 0 +#endif + +#ifndef INCLUDE_xSemaphoreGetMutexHolder + #define INCLUDE_xSemaphoreGetMutexHolder INCLUDE_xQueueGetMutexHolder +#endif + +#ifndef INCLUDE_xTaskGetHandle + #define INCLUDE_xTaskGetHandle 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark + #define INCLUDE_uxTaskGetStackHighWaterMark 0 +#endif + +#ifndef INCLUDE_uxTaskGetStackHighWaterMark2 + #define INCLUDE_uxTaskGetStackHighWaterMark2 0 +#endif + +#ifndef INCLUDE_eTaskGetState + #define INCLUDE_eTaskGetState 0 +#endif + +#ifndef INCLUDE_xTaskResumeFromISR + #define INCLUDE_xTaskResumeFromISR 1 +#endif + +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 +#endif + +#ifndef INCLUDE_xTaskGetSchedulerState + #define INCLUDE_xTaskGetSchedulerState 0 +#endif + +#ifndef INCLUDE_xTaskGetCurrentTaskHandle + #define INCLUDE_xTaskGetCurrentTaskHandle 0 +#endif + +#if configUSE_CO_ROUTINES != 0 + #ifndef configMAX_CO_ROUTINE_PRIORITIES + #error configMAX_CO_ROUTINE_PRIORITIES must be greater than or equal to 1. + #endif +#endif + +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 +#endif + +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif + +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 +#endif + +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 0 +#endif + +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 0 +#endif + +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 +#endif + +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 0 +#endif + +#ifndef configUSE_ALTERNATIVE_API + #define configUSE_ALTERNATIVE_API 0 +#endif + +#ifndef portCRITICAL_NESTING_IN_TCB + #define portCRITICAL_NESTING_IN_TCB 0 +#endif + +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 16 +#endif + +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 +#endif + +#if configMAX_TASK_NAME_LEN < 1 + #error configMAX_TASK_NAME_LEN must be set to a minimum of 1 in FreeRTOSConfig.h +#endif + +#ifndef configASSERT + #define configASSERT( x ) + #define configASSERT_DEFINED 0 +#else + #define configASSERT_DEFINED 1 +#endif + +#ifndef portMEMORY_BARRIER + #define portMEMORY_BARRIER() +#endif + +/* The timers module relies on xTaskGetSchedulerState(). */ +#if configUSE_TIMERS == 1 + + #ifndef configTIMER_TASK_PRIORITY + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_PRIORITY must also be defined. + #endif /* configTIMER_TASK_PRIORITY */ + + #ifndef configTIMER_QUEUE_LENGTH + #error If configUSE_TIMERS is set to 1 then configTIMER_QUEUE_LENGTH must also be defined. + #endif /* configTIMER_QUEUE_LENGTH */ + + #ifndef configTIMER_TASK_STACK_DEPTH + #error If configUSE_TIMERS is set to 1 then configTIMER_TASK_STACK_DEPTH must also be defined. + #endif /* configTIMER_TASK_STACK_DEPTH */ + +#endif /* configUSE_TIMERS */ + +#ifndef portSET_INTERRUPT_MASK_FROM_ISR + #define portSET_INTERRUPT_MASK_FROM_ISR() 0 +#endif + +#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR + #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue +#endif + +#ifndef portCLEAN_UP_TCB + #define portCLEAN_UP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef portPRE_TASK_DELETE_HOOK + #define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxYieldPending ) +#endif + +#ifndef portSETUP_TCB + #define portSETUP_TCB( pxTCB ) ( void ) pxTCB +#endif + +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 0U +#endif + +#if ( configQUEUE_REGISTRY_SIZE < 1 ) + #define vQueueAddToRegistry( xQueue, pcName ) + #define vQueueUnregisterQueue( xQueue ) + #define pcQueueGetName( xQueue ) +#endif + +#ifndef portPOINTER_SIZE_TYPE + #define portPOINTER_SIZE_TYPE uint32_t +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + #include "SEGGER_SYSVIEW_FreeRTOS.h" /* include Segger System Viewer macro definitions */ +#endif + +/* Remove any unused trace macros. */ +#ifndef traceSTART + /* Used to perform any necessary initialisation - for example, open a file + into which trace is to be written. */ + #define traceSTART() +#endif + +#ifndef traceEND + /* Use to close a trace, for example close a file into which trace has been + written. */ + #define traceEND() +#endif + +#ifndef traceTASK_SWITCHED_IN + /* Called after a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the selected task. */ + #define traceTASK_SWITCHED_IN() +#endif + +#ifndef traceINCREASE_TICK_COUNT + /* Called before stepping the tick count after waking from tickless idle + sleep. */ + #define traceINCREASE_TICK_COUNT( x ) +#endif + +#ifndef traceLOW_POWER_IDLE_BEGIN + /* Called immediately before entering tickless idle. */ + #define traceLOW_POWER_IDLE_BEGIN() +#endif + +#ifndef traceLOW_POWER_IDLE_END + /* Called when returning to the Idle task after a tickless idle. */ + #define traceLOW_POWER_IDLE_END() +#endif + +#ifndef traceTASK_SWITCHED_OUT + /* Called before a task has been selected to run. pxCurrentTCB holds a pointer + to the task control block of the task being switched out. */ + #define traceTASK_SWITCHED_OUT() +#endif + +#ifndef traceTASK_PRIORITY_INHERIT + /* Called when a task attempts to take a mutex that is already held by a + lower priority task. pxTCBOfMutexHolder is a pointer to the TCB of the task + that holds the mutex. uxInheritedPriority is the priority the mutex holder + will inherit (the priority of the task that is attempting to obtain the + muted. */ + #define traceTASK_PRIORITY_INHERIT( pxTCBOfMutexHolder, uxInheritedPriority ) +#endif + +#ifndef traceTASK_PRIORITY_DISINHERIT + /* Called when a task releases a mutex, the holding of which had resulted in + the task inheriting the priority of a higher priority task. + pxTCBOfMutexHolder is a pointer to the TCB of the task that is releasing the + mutex. uxOriginalPriority is the task's configured (base) priority. */ + #define traceTASK_PRIORITY_DISINHERIT( pxTCBOfMutexHolder, uxOriginalPriority ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_RECEIVE + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_PEEK + /* Task is about to block because it cannot read from a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the read was attempted. pxCurrentTCB points to the TCB of the + task that attempted the read. */ + #define traceBLOCKING_ON_QUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceBLOCKING_ON_QUEUE_SEND + /* Task is about to block because it cannot write to a + queue/mutex/semaphore. pxQueue is a pointer to the queue/mutex/semaphore + upon which the write was attempted. pxCurrentTCB points to the TCB of the + task that attempted the write. */ + #define traceBLOCKING_ON_QUEUE_SEND( pxQueue ) +#endif + +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 0 +#endif + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 0 +#endif + +#ifndef configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H + #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 0 +#endif + +/* The following event macros are embedded in the kernel API calls. */ + +#ifndef traceMOVED_TASK_TO_READY_STATE + #define traceMOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef tracePOST_MOVED_TASK_TO_READY_STATE + #define tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +#endif + +#ifndef traceQUEUE_CREATE + #define traceQUEUE_CREATE( pxNewQueue ) +#endif + +#ifndef traceQUEUE_CREATE_FAILED + #define traceQUEUE_CREATE_FAILED( ucQueueType ) +#endif + +#ifndef traceCREATE_MUTEX + #define traceCREATE_MUTEX( pxNewQueue ) +#endif + +#ifndef traceCREATE_MUTEX_FAILED + #define traceCREATE_MUTEX_FAILED() +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE + #define traceGIVE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceGIVE_MUTEX_RECURSIVE_FAILED + #define traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE + #define traceTAKE_MUTEX_RECURSIVE( pxMutex ) +#endif + +#ifndef traceTAKE_MUTEX_RECURSIVE_FAILED + #define traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ) +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE + #define traceCREATE_COUNTING_SEMAPHORE() +#endif + +#ifndef traceCREATE_COUNTING_SEMAPHORE_FAILED + #define traceCREATE_COUNTING_SEMAPHORE_FAILED() +#endif + +#ifndef traceQUEUE_SEND + #define traceQUEUE_SEND( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FAILED + #define traceQUEUE_SEND_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE + #define traceQUEUE_RECEIVE( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK + #define traceQUEUE_PEEK( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FAILED + #define traceQUEUE_PEEK_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR + #define traceQUEUE_PEEK_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FAILED + #define traceQUEUE_RECEIVE_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR + #define traceQUEUE_SEND_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_SEND_FROM_ISR_FAILED + #define traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR + #define traceQUEUE_RECEIVE_FROM_ISR( pxQueue ) +#endif + +#ifndef traceQUEUE_RECEIVE_FROM_ISR_FAILED + #define traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_PEEK_FROM_ISR_FAILED + #define traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ) +#endif + +#ifndef traceQUEUE_DELETE + #define traceQUEUE_DELETE( pxQueue ) +#endif + +#ifndef traceTASK_CREATE + #define traceTASK_CREATE( pxNewTCB ) +#endif + +#ifndef traceTASK_CREATE_FAILED + #define traceTASK_CREATE_FAILED() +#endif + +#ifndef traceTASK_DELETE + #define traceTASK_DELETE( pxTaskToDelete ) +#endif + +#ifndef traceTASK_DELAY_UNTIL + #define traceTASK_DELAY_UNTIL( x ) +#endif + +#ifndef traceTASK_DELAY + #define traceTASK_DELAY() +#endif + +#ifndef traceTASK_PRIORITY_SET + #define traceTASK_PRIORITY_SET( pxTask, uxNewPriority ) +#endif + +#ifndef traceTASK_SUSPEND + #define traceTASK_SUSPEND( pxTaskToSuspend ) +#endif + +#ifndef traceTASK_RESUME + #define traceTASK_RESUME( pxTaskToResume ) +#endif + +#ifndef traceTASK_RESUME_FROM_ISR + #define traceTASK_RESUME_FROM_ISR( pxTaskToResume ) +#endif + +#ifndef traceTASK_INCREMENT_TICK + #define traceTASK_INCREMENT_TICK( xTickCount ) +#endif + +#ifndef traceTIMER_CREATE + #define traceTIMER_CREATE( pxNewTimer ) +#endif + +#ifndef traceTIMER_CREATE_FAILED + #define traceTIMER_CREATE_FAILED() +#endif + +#ifndef traceTIMER_COMMAND_SEND + #define traceTIMER_COMMAND_SEND( xTimer, xMessageID, xMessageValueValue, xReturn ) +#endif + +#ifndef traceTIMER_EXPIRED + #define traceTIMER_EXPIRED( pxTimer ) +#endif + +#ifndef traceTIMER_COMMAND_RECEIVED + #define traceTIMER_COMMAND_RECEIVED( pxTimer, xMessageID, xMessageValue ) +#endif + +#ifndef traceMALLOC + #define traceMALLOC( pvAddress, uiSize ) +#endif + +#ifndef traceFREE + #define traceFREE( pvAddress, uiSize ) +#endif + +#ifndef traceEVENT_GROUP_CREATE + #define traceEVENT_GROUP_CREATE( xEventGroup ) +#endif + +#ifndef traceEVENT_GROUP_CREATE_FAILED + #define traceEVENT_GROUP_CREATE_FAILED() +#endif + +#ifndef traceEVENT_GROUP_SYNC_BLOCK + #define traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_SYNC_END + #define traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_BLOCK + #define traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ) +#endif + +#ifndef traceEVENT_GROUP_WAIT_BITS_END + #define traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ) ( void ) xTimeoutOccurred +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS + #define traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_CLEAR_BITS_FROM_ISR + #define traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS + #define traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_SET_BITS_FROM_ISR + #define traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ) +#endif + +#ifndef traceEVENT_GROUP_DELETE + #define traceEVENT_GROUP_DELETE( xEventGroup ) +#endif + +#ifndef tracePEND_FUNC_CALL + #define tracePEND_FUNC_CALL(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef tracePEND_FUNC_CALL_FROM_ISR + #define tracePEND_FUNC_CALL_FROM_ISR(xFunctionToPend, pvParameter1, ulParameter2, ret) +#endif + +#ifndef traceQUEUE_REGISTRY_ADD + #define traceQUEUE_REGISTRY_ADD(xQueue, pcQueueName) +#endif + +#ifndef traceTASK_NOTIFY_TAKE_BLOCK + #define traceTASK_NOTIFY_TAKE_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_TAKE + #define traceTASK_NOTIFY_TAKE() +#endif + +#ifndef traceTASK_NOTIFY_WAIT_BLOCK + #define traceTASK_NOTIFY_WAIT_BLOCK() +#endif + +#ifndef traceTASK_NOTIFY_WAIT + #define traceTASK_NOTIFY_WAIT() +#endif + +#ifndef traceTASK_NOTIFY + #define traceTASK_NOTIFY() +#endif + +#ifndef traceTASK_NOTIFY_FROM_ISR + #define traceTASK_NOTIFY_FROM_ISR() +#endif + +#ifndef traceTASK_NOTIFY_GIVE_FROM_ISR + #define traceTASK_NOTIFY_GIVE_FROM_ISR() +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_FAILED + #define traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE_STATIC_FAILED + #define traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_CREATE + #define traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_DELETE + #define traceSTREAM_BUFFER_DELETE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RESET + #define traceSTREAM_BUFFER_RESET( xStreamBuffer ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_SEND + #define traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND + #define traceSTREAM_BUFFER_SEND( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FAILED + #define traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_SEND_FROM_ISR + #define traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xBytesSent ) +#endif + +#ifndef traceBLOCKING_ON_STREAM_BUFFER_RECEIVE + #define traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE + #define traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FAILED + #define traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ) +#endif + +#ifndef traceSTREAM_BUFFER_RECEIVE_FROM_ISR + #define traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ) +#endif + +#if 1 /* << EST additional trace entries used by Segger SystemView */ + +#ifndef traceISR_ENTER + #define traceISR_ENTER() +#endif + +#ifndef traceISR_EXIT_TO_SCHEDULER + #define traceISR_EXIT_TO_SCHEDULER() +#endif + +#ifndef traceISR_EXIT + #define traceISR_EXIT() +#endif + +#ifndef traceMOVED_TASK_TO_SUSPENDED_LIST + #define traceMOVED_TASK_TO_SUSPENDED_LIST(x) +#endif + +#ifndef traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST + #define traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST() +#endif + +#ifndef traceMOVED_TASK_TO_DELAYED_LIST + #define traceMOVED_TASK_TO_DELAYED_LIST() +#endif + +#endif /* << EST */ + +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 0 +#endif + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + #ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #error If configGENERATE_RUN_TIME_STATS is defined then portCONFIGURE_TIMER_FOR_RUN_TIME_STATS must also be defined. portCONFIGURE_TIMER_FOR_RUN_TIME_STATS should call a port layer function to setup a peripheral timer/counter that can then be used as the run time counter time base. + #endif /* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS */ + + #ifndef portGET_RUN_TIME_COUNTER_VALUE + #ifndef portALT_GET_RUN_TIME_COUNTER_VALUE + #error If configGENERATE_RUN_TIME_STATS is defined then either portGET_RUN_TIME_COUNTER_VALUE or portALT_GET_RUN_TIME_COUNTER_VALUE must also be defined. See the examples provided and the FreeRTOS web site for more information. + #endif /* portALT_GET_RUN_TIME_COUNTER_VALUE */ + #endif /* portGET_RUN_TIME_COUNTER_VALUE */ + +#endif /* configGENERATE_RUN_TIME_STATS */ + +#ifndef portCONFIGURE_TIMER_FOR_RUN_TIME_STATS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() +#endif + +#ifndef configUSE_MALLOC_FAILED_HOOK + #define configUSE_MALLOC_FAILED_HOOK 0 +#endif + +#ifndef portPRIVILEGE_BIT + #define portPRIVILEGE_BIT ( ( UBaseType_t ) 0x00 ) +#endif + +#ifndef portYIELD_WITHIN_API + #define portYIELD_WITHIN_API portYIELD +#endif + +#ifndef portSUPPRESS_TICKS_AND_SLEEP + #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) +#endif + +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 +#endif + +#if configEXPECTED_IDLE_TIME_BEFORE_SLEEP < 2 + #error configEXPECTED_IDLE_TIME_BEFORE_SLEEP must not be less than 2 +#endif + +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 +#endif + +#ifndef configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING + #define configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPRE_SLEEP_PROCESSING + #define configPRE_SLEEP_PROCESSING( x ) +#endif + +#ifndef configPOST_SLEEP_PROCESSING + #define configPOST_SLEEP_PROCESSING( x ) +#endif + +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif + +#ifndef portTASK_USES_FLOATING_POINT + #define portTASK_USES_FLOATING_POINT() +#endif + +#ifndef portALLOCATE_SECURE_CONTEXT + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) +#endif + +#ifndef portDONT_DISCARD + #define portDONT_DISCARD +#endif + +#ifndef configUSE_TIME_SLICING + #define configUSE_TIME_SLICING 1 +#endif + +#ifndef configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS + #define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0 +#endif + +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#endif + +#ifndef portASSERT_IF_INTERRUPT_PRIORITY_INVALID + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif + +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 0 +#endif + +#ifndef mtCOVERAGE_TEST_MARKER + #define mtCOVERAGE_TEST_MARKER() +#endif + +#ifndef mtCOVERAGE_TEST_DELAY + #define mtCOVERAGE_TEST_DELAY() +#endif + +#ifndef portASSERT_IF_IN_ISR + #define portASSERT_IF_IN_ISR() +#endif + +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#endif + +#ifndef configAPPLICATION_ALLOCATED_HEAP + #define configAPPLICATION_ALLOCATED_HEAP 0 +#endif + +#ifndef configUSE_TASK_NOTIFICATIONS + #define configUSE_TASK_NOTIFICATIONS 1 +#endif + +#ifndef configUSE_POSIX_ERRNO + #define configUSE_POSIX_ERRNO 0 +#endif + +#ifndef portTICK_TYPE_IS_ATOMIC + #define portTICK_TYPE_IS_ATOMIC 0 +#endif + +#ifndef configSUPPORT_STATIC_ALLOCATION + /* Defaults to 0 for backward compatibility. */ + #define configSUPPORT_STATIC_ALLOCATION 0 +#endif + +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + /* Defaults to 1 for backward compatibility. */ + #define configSUPPORT_DYNAMIC_ALLOCATION 1 +#endif + +#ifndef configSTACK_DEPTH_TYPE + /* Defaults to uint16_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if uint16_t is too restrictive. */ + #define configSTACK_DEPTH_TYPE uint16_t +#endif + +#ifndef configMESSAGE_BUFFER_LENGTH_TYPE + /* Defaults to size_t for backward compatibility, but can be overridden + in FreeRTOSConfig.h if lengths will always be less than the number of bytes + in a size_t. */ + #define configMESSAGE_BUFFER_LENGTH_TYPE size_t +#endif + +/* Sanity check the configuration. */ +#if( configUSE_TICKLESS_IDLE != 0 ) + #if( INCLUDE_vTaskSuspend != 1 ) + #error INCLUDE_vTaskSuspend must be set to 1 if configUSE_TICKLESS_IDLE is not set to 0 + #endif /* INCLUDE_vTaskSuspend */ +#endif /* configUSE_TICKLESS_IDLE */ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) ) + #error configSUPPORT_STATIC_ALLOCATION and configSUPPORT_DYNAMIC_ALLOCATION cannot both be 0, but can both be 1. +#endif + +#if( ( configUSE_RECURSIVE_MUTEXES == 1 ) && ( configUSE_MUTEXES != 1 ) ) + #error configUSE_MUTEXES must be set to 1 to use recursive mutexes +#endif + +#ifndef configINITIAL_TICK_COUNT + #define configINITIAL_TICK_COUNT 0 +#endif + +#if( portTICK_TYPE_IS_ATOMIC == 0 ) + /* Either variables of tick type cannot be read atomically, or + portTICK_TYPE_IS_ATOMIC was not set - map the critical sections used when + the tick count is returned to the standard critical section macros. */ + #define portTICK_TYPE_ENTER_CRITICAL() portENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() portEXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( ( x ) ) +#else + /* The tick type can be read atomically, so critical sections used when the + tick count is returned can be defined away. */ + #define portTICK_TYPE_ENTER_CRITICAL() + #define portTICK_TYPE_EXIT_CRITICAL() + #define portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR() 0 + #define portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( x ) ( void ) x +#endif + +/* Definitions to allow backward compatibility with FreeRTOS versions prior to +V8 if desired. */ +#ifndef configENABLE_BACKWARD_COMPATIBILITY + #define configENABLE_BACKWARD_COMPATIBILITY 1 +#endif + +#ifndef configPRINTF + /* configPRINTF() was not defined, so define it away to nothing. To use + configPRINTF() then define it as follows (where MyPrintFunction() is + provided by the application writer): + + void MyPrintFunction(const char *pcFormat, ... ); + #define configPRINTF( X ) MyPrintFunction X + + Then call like a standard printf() function, but placing brackets around + all parameters so they are passed as a single parameter. For example: + configPRINTF( ("Value = %d", MyVariable) ); */ + #define configPRINTF( X ) +#endif + +#ifndef configMAX + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMAX( a, b ) ( ( ( a ) > ( b ) ) ? ( a ) : ( b ) ) +#endif + +#ifndef configMIN + /* The application writer has not provided their own MAX macro, so define + the following generic implementation. */ + #define configMIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) ) +#endif + +#if configENABLE_BACKWARD_COMPATIBILITY == 1 + #define eTaskStateGet eTaskGetState + #define portTickType TickType_t + #define xTaskHandle TaskHandle_t + #define xQueueHandle QueueHandle_t + #define xSemaphoreHandle SemaphoreHandle_t + #define xQueueSetHandle QueueSetHandle_t + #define xQueueSetMemberHandle QueueSetMemberHandle_t + #define xTimeOutType TimeOut_t + #define xMemoryRegion MemoryRegion_t + #define xTaskParameters TaskParameters_t + #define xTaskStatusType TaskStatus_t + #define xTimerHandle TimerHandle_t + #define xCoRoutineHandle CoRoutineHandle_t + #define pdTASK_HOOK_CODE TaskHookFunction_t + #define portTICK_RATE_MS portTICK_PERIOD_MS + #define pcTaskGetTaskName pcTaskGetName + #define pcTimerGetTimerName pcTimerGetName + #define pcQueueGetQueueName pcQueueGetName + #define vTaskGetTaskInfo vTaskGetInfo + + /* Backward compatibility within the scheduler code only - these definitions + are not really required but are included for completeness. */ + #define tmrTIMER_CALLBACK TimerCallbackFunction_t + #define pdTASK_CODE TaskFunction_t + #define xListItem ListItem_t + #define xList List_t + + /* For libraries that break the list data hiding, and access list structure + members directly (which is not supposed to be done). */ + #define pxContainer pvContainer +#endif /* configENABLE_BACKWARD_COMPATIBILITY */ + +#if( configUSE_ALTERNATIVE_API != 0 ) + #error The alternative API was deprecated some time ago, and was removed in FreeRTOS V9.0 0 +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#ifndef configUSE_TASK_FPU_SUPPORT + #define configUSE_TASK_FPU_SUPPORT 1 +#endif + +/* Set configENABLE_MPU to 1 to enable MPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_MPU + #define configENABLE_MPU 0 +#endif + +/* Set configENABLE_FPU to 1 to enable FPU support and 0 to disable it. This is +currently used in ARMv8M ports. */ +#ifndef configENABLE_FPU + #define configENABLE_FPU 1 +#endif + +/* Set configENABLE_TRUSTZONE to 1 enable TrustZone support and 0 to disable it. +This is currently used in ARMv8M ports. */ +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE 1 +#endif + +/* Set configRUN_FREERTOS_SECURE_ONLY to 1 to run the FreeRTOS ARMv8M port on +the Secure Side only. */ +#ifndef configRUN_FREERTOS_SECURE_ONLY + #define configRUN_FREERTOS_SECURE_ONLY 0 +#endif + +/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using + * dynamically allocated RAM, in which case when any task is deleted it is known + * that both the task's stack and TCB need to be freed. Sometimes the + * FreeRTOSConfig.h settings only allow a task to be created using statically + * allocated RAM, in which case when any task is deleted it is known that neither + * the task's stack or TCB should be freed. Sometimes the FreeRTOSConfig.h + * settings allow a task to be created using either statically or dynamically + * allocated RAM, in which case a member of the TCB is used to record whether the + * stack and/or TCB were allocated statically or dynamically, so when a task is + * deleted the RAM that was allocated dynamically is freed again and no attempt is + * made to free the RAM that was allocated statically. + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE is only true if it is possible for a + * task to be created using either statically or dynamically allocated RAM. Note + * that if portUSING_MPU_WRAPPERS is 1 then a protected task can be created with + * a statically allocated stack and a dynamically allocated TCB. + * + * The following table lists various combinations of portUSING_MPU_WRAPPERS, + * configSUPPORT_DYNAMIC_ALLOCATION and configSUPPORT_STATIC_ALLOCATION and + * when it is possible to have both static and dynamic allocation: + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | MPU | Dynamic | Static | Available Functions | Possible Allocations | Both Dynamic and | Need Free | + * | | | | | | Static Possible | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + * | 0 | 0 | 1 | xTaskCreateStatic | TCB - Static, Stack - Static | No | No | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 0 | xTaskCreate | TCB - Dynamic, Stack - Dynamic | No | Yes | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 0 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic | 2. TCB - Static, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 0 | 1 | xTaskCreateStatic, | TCB - Static, Stack - Static | No | No | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 0 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateRestricted | 2. TCB - Dynamic, Stack - Static | | | + * +-----|---------|--------|-----------------------------|-----------------------------------|------------------|-----------| + * | 1 | 1 | 1 | xTaskCreate, | 1. TCB - Dynamic, Stack - Dynamic | Yes | Yes | + * | | | | xTaskCreateStatic, | 2. TCB - Dynamic, Stack - Static | | | + * | | | | xTaskCreateRestricted, | 3. TCB - Static, Stack - Static | | | + * | | | | xTaskCreateRestrictedStatic | | | | + * +-----+---------+--------+-----------------------------+-----------------------------------+------------------+-----------+ + */ +#define tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE ( ( ( portUSING_MPU_WRAPPERS == 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) || \ + ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) ) + +/* + * In line with software engineering best practice, FreeRTOS implements a strict + * data hiding policy, so the real structures used by FreeRTOS to maintain the + * state of tasks, queues, semaphores, etc. are not accessible to the application + * code. However, if the application writer wants to statically allocate such + * an object then the size of the object needs to be know. Dummy structures + * that are guaranteed to have the same size and alignment requirements of the + * real objects are used for this purpose. The dummy list and list item + * structures below are used for inclusion in such a dummy structure. + */ +struct xSTATIC_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 4 ]; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy4; + #endif +}; +typedef struct xSTATIC_LIST_ITEM StaticListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +struct xSTATIC_MINI_LIST_ITEM +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + TickType_t xDummy2; + void *pvDummy3[ 2 ]; +}; +typedef struct xSTATIC_MINI_LIST_ITEM StaticMiniListItem_t; + +/* See the comments above the struct xSTATIC_LIST_ITEM definition. */ +typedef struct xSTATIC_LIST +{ + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy1; + #endif + UBaseType_t uxDummy2; + void *pvDummy3; + StaticMiniListItem_t xDummy4; + #if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 1 ) + TickType_t xDummy5; + #endif +} StaticList_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Task structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a task then + * the size of the task object needs to be know. The StaticTask_t structure + * below is provided for this purpose. Its sizes and alignment requirements are + * guaranteed to match those of the genuine structure, no matter which + * architecture is being used, and no matter how the values in FreeRTOSConfig.h + * are set. Its contents are somewhat obfuscated in the hope users will + * recognise that it would be unwise to make direct use of the structure members. + */ +typedef struct xSTATIC_TCB +{ + void *pxDummy1; + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xDummy2; + #endif + StaticListItem_t xDummy3[ 2 ]; + UBaseType_t uxDummy5; + void *pxDummy6; + uint8_t ucDummy7[ configMAX_TASK_NAME_LEN ]; + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + void *pxDummy8; + #endif + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxDummy9; + #endif + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy10[ 2 ]; + #endif + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxDummy12[ 2 ]; + #endif + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void *pxDummy14; + #endif + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvDummy15[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulDummy16; + #endif + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + struct _reent xDummy17; + #endif + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t ulDummy18; + uint8_t ucDummy19; + #endif + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + uint8_t uxDummy20; + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDummy21; + #endif + #if ( configUSE_POSIX_ERRNO == 1 ) + int iDummy22; + #endif +} StaticTask_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the Queue structure used internally by + * FreeRTOS is not accessible to application code. However, if the application + * writer wants to statically allocate the memory required to create a queue + * then the size of the queue object needs to be know. The StaticQueue_t + * structure below is provided for this purpose. Its sizes and alignment + * requirements are guaranteed to match those of the genuine structure, no + * matter which architecture is being used, and no matter how the values in + * FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in the hope + * users will recognise that it would be unwise to make direct use of the + * structure members. + */ +typedef struct xSTATIC_QUEUE +{ + void *pvDummy1[ 3 ]; + + union + { + void *pvDummy2; + UBaseType_t uxDummy2; + } u; + + StaticList_t xDummy3[ 2 ]; + UBaseType_t uxDummy4[ 3 ]; + uint8_t ucDummy5[ 2 ]; + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy6; + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + void *pvDummy7; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy8; + uint8_t ucDummy9; + #endif + +} StaticQueue_t; +typedef StaticQueue_t StaticSemaphore_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the event group structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create an event group then the size of the event group object needs to be + * know. The StaticEventGroup_t structure below is provided for this purpose. + * Its sizes and alignment requirements are guaranteed to match those of the + * genuine structure, no matter which architecture is being used, and no matter + * how the values in FreeRTOSConfig.h are set. Its contents are somewhat + * obfuscated in the hope users will recognise that it would be unwise to make + * direct use of the structure members. + */ +typedef struct xSTATIC_EVENT_GROUP +{ + TickType_t xDummy1; + StaticList_t xDummy2; + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy3; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucDummy4; + #endif + +} StaticEventGroup_t; + +/* + * In line with software engineering best practice, especially when supplying a + * library that is likely to change in future versions, FreeRTOS implements a + * strict data hiding policy. This means the software timer structure used + * internally by FreeRTOS is not accessible to application code. However, if + * the application writer wants to statically allocate the memory required to + * create a software timer then the size of the queue object needs to be know. + * The StaticTimer_t structure below is provided for this purpose. Its sizes + * and alignment requirements are guaranteed to match those of the genuine + * structure, no matter which architecture is being used, and no matter how the + * values in FreeRTOSConfig.h are set. Its contents are somewhat obfuscated in + * the hope users will recognise that it would be unwise to make direct use of + * the structure members. + */ +typedef struct xSTATIC_TIMER +{ + void *pvDummy1; + StaticListItem_t xDummy2; + TickType_t xDummy3; + void *pvDummy5; + TaskFunction_t pvDummy6; + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy7; + #endif + uint8_t ucDummy8; + +} StaticTimer_t; + +/* +* In line with software engineering best practice, especially when supplying a +* library that is likely to change in future versions, FreeRTOS implements a +* strict data hiding policy. This means the stream buffer structure used +* internally by FreeRTOS is not accessible to application code. However, if +* the application writer wants to statically allocate the memory required to +* create a stream buffer then the size of the stream buffer object needs to be +* know. The StaticStreamBuffer_t structure below is provided for this purpose. +* Its size and alignment requirements are guaranteed to match those of the +* genuine structure, no matter which architecture is being used, and no matter +* how the values in FreeRTOSConfig.h are set. Its contents are somewhat +* obfuscated in the hope users will recognise that it would be unwise to make +* direct use of the structure members. +*/ +typedef struct xSTATIC_STREAM_BUFFER +{ + size_t uxDummy1[ 4 ]; + void * pvDummy2[ 3 ]; + uint8_t ucDummy3; + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxDummy4; + #endif +} StaticStreamBuffer_t; + +/* Message buffers are built on stream buffers. */ +typedef StaticStreamBuffer_t StaticMessageBuffer_t; + +#ifdef __cplusplus +} +#endif + +#endif /* INC_FREERTOS_H */ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* << EST */ + #include "trcRecorder.h" +#endif + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOSConfig.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOSConfig.h new file mode 100644 index 0000000..9bd8045 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOSConfig.h @@ -0,0 +1,305 @@ +/* + * FreeRTOS Kernel V10.1.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include "MCUC1.h" /* SDK and API used */ +#include "FRTOS1config.h" /* extra configuration settings not part of the original FreeRTOS ports */ + +#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1 /* 1: include additional header file at the end of task.c to help with debugging in GDB in combination with configUSE_TRACE_FACILITY; 0: no extra file included. */ +#define configENABLE_BACKWARD_COMPATIBILITY 0 /* 1: enable backward compatibility mode, using old names in kernel. 0: use new kernel structure names (recommended) */ +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ +#ifndef configGENERATE_RUN_TIME_STATS_USE_TICKS + #define configGENERATE_RUN_TIME_STATS_USE_TICKS 0 /* 1: Use the RTOS tick counter as runtime counter. 0: use extra timer */ +#endif +#ifndef configGENERATE_RUN_TIME_STATS + #define configGENERATE_RUN_TIME_STATS 1 /* 1: generate runtime statistics; 0: no runtime statistics */ +#endif +#if configGENERATE_RUN_TIME_STATS + #if configGENERATE_RUN_TIME_STATS_USE_TICKS + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ /* default: use Tick counter as runtime counter */ + #define portGET_RUN_TIME_COUNTER_VALUE() xTaskGetTickCountFromISR() /* default: use Tick counter as runtime counter */ + #else /* use dedicated timer */ + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() FRTOS1_AppConfigureTimerForRuntimeStats() + #define portGET_RUN_TIME_COUNTER_VALUE() FRTOS1_AppGetRuntimeCounterValueFromISR() + #endif +#else /* no runtime stats, use empty macros */ + #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() /* nothing */ + #define portGET_RUN_TIME_COUNTER_VALUE() /* nothing */ +#endif +#define configUSE_PREEMPTION 1 /* 1: pre-emptive mode; 0: cooperative mode */ +#define configUSE_TIME_SLICING 1 /* 1: use time slicing; 0: don't time slice at tick interrupt time */ +#define configUSE_IDLE_HOOK 1 /* 1: use Idle hook; 0: no Idle hook */ +#define configUSE_IDLE_HOOK_NAME FRTOS1_vApplicationIdleHook +#define configUSE_TICK_HOOK 1 /* 1: use Tick hook; 0: no Tick hook */ +#define configUSE_TICK_HOOK_NAME FRTOS1_vApplicationTickHook +#define configUSE_MALLOC_FAILED_HOOK 1 /* 1: use MallocFailed hook; 0: no MallocFailed hook */ +#define configUSE_MALLOC_FAILED_HOOK_NAME FRTOS1_vApplicationMallocFailedHook +#ifndef configTICK_RATE_HZ + #define configTICK_RATE_HZ (1000) /* frequency of tick interrupt */ +#endif +#define configSYSTICK_USE_LOW_POWER_TIMER 0 /* If using Kinetis Low Power Timer (LPTMR) instead of SysTick timer */ +#define configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ 1 /* 1 kHz LPO timer. Set to 1 if not used */ +#if MCUC1_CONFIG_NXP_SDK_USED || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_GENERIC || MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_NORDIC_NRF5 +/* The CMSIS variable SystemCoreClock contains the current clock speed */ + extern uint32_t SystemCoreClock; + #define configCPU_CLOCK_HZ SystemCoreClock /* CPU clock frequency */ + #define configBUS_CLOCK_HZ SystemCoreClock /* Bus clock frequency */ +#else + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) /* Kinetis defines this one in Cpu.h */ + #define configCPU_CLOCK_HZ CPU_CORE_CLK_HZ /* CPU core clock defined in Cpu.h */ + #else + #define configCPU_CLOCK_HZ CPU_INSTR_CLK_HZ /* CPU core clock defined in Cpu.h */ + #endif + #define configBUS_CLOCK_HZ CPU_BUS_CLK_HZ /* CPU bus clock defined in Cpu.h */ +#endif /* #if MCUC1_CONFIG_NXP_SDK_USED */ +#define configSYSTICK_USE_CORE_CLOCK 1 /* System Tick is using core clock */ +#define configSYSTICK_CLOCK_DIVIDER 1 /* no divider */ +#define configSYSTICK_CLOCK_HZ ((configCPU_CLOCK_HZ)/configSYSTICK_CLOCK_DIVIDER) /* frequency of system tick counter */ +#ifndef configMINIMAL_STACK_SIZE + #define configMINIMAL_STACK_SIZE (100) /* stack size in addressable stack units */ +#endif +/*----------------------------------------------------------*/ +/* Heap Memory */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 1 /* either 1 (only alloc), 2 (alloc/free), 3 (malloc), 4 (coalesc blocks), 5 (multiple blocks), 6 (newlib) */ +#endif /* configUSE_HEAP_SCHEME */ +#define configFRTOS_MEMORY_SCHEME configUSE_HEAP_SCHEME /* for backwards compatible only with legacy name */ +#ifndef configTOTAL_HEAP_SIZE + #define configTOTAL_HEAP_SIZE (4000) /* size of heap in bytes */ +#endif /* configTOTAL_HEAP_SIZE */ +#ifndef configUSE_HEAP_SECTION_NAME + #define configUSE_HEAP_SECTION_NAME 0 /* set to 1 if a custom section name (configHEAP_SECTION_NAME_STRING) shall be used, 0 otherwise */ +#endif +#ifndef configHEAP_SECTION_NAME_STRING + #define configHEAP_SECTION_NAME_STRING ".m_data_20000000" /* heap section name (use e.g. ".m_data_20000000" for KDS/gcc, ".bss.$SRAM_LOWER.FreeRTOS" for MCUXpresso or "m_data_20000000" for IAR). Check your linker file for the name used. */ +#endif +#define configAPPLICATION_ALLOCATED_HEAP 0 /* set to one if application is defining heap ucHeap[] variable, 0 otherwise */ +#ifndef configSUPPORT_DYNAMIC_ALLOCATION + #define configSUPPORT_DYNAMIC_ALLOCATION 1 /* 1: make dynamic allocation functions for RTOS available. 0: only static functions are allowed */ +#endif +#ifndef configSUPPORT_STATIC_ALLOCATION + #define configSUPPORT_STATIC_ALLOCATION 0 /* 1: make static allocation functions for RTOS available. 0: only dynamic functions are allowed */ +#endif +#define configUSE_NEWLIB_REENTRANT (configUSE_HEAP_SCHEME==6) /* 1: a newlib reent structure will be allocated for each task; 0: no such reentr structure used */ +/*----------------------------------------------------------*/ +#ifndef configMAX_TASK_NAME_LEN + #define configMAX_TASK_NAME_LEN 12 /* task name length in bytes */ +#endif +#ifndef configUSE_TRACE_FACILITY + #define configUSE_TRACE_FACILITY 1 /* 1: include additional structure members and functions to assist with execution visualization and tracing, 0: no runtime stats/trace */ +#endif +#ifndef configUSE_STATS_FORMATTING_FUNCTIONS + #define configUSE_STATS_FORMATTING_FUNCTIONS (configUSE_TRACE_FACILITY || configGENERATE_RUN_TIME_STATS) +#endif +#define configUSE_16_BIT_TICKS 0 /* 1: use 16bit tick counter type, 0: use 32bit tick counter type */ +#ifndef configIDLE_SHOULD_YIELD + #define configIDLE_SHOULD_YIELD 1 /* 1: the IDEL task will yield as soon as possible. 0: The IDLE task waits until preemption. */ +#endif +#ifndef configUSE_PORT_OPTIMISED_TASK_SELECTION + #define configUSE_PORT_OPTIMISED_TASK_SELECTION (1 && configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY)) /* 1: the scheduler uses an optimized task selection as defined by the port (if available). 0: normal task selection is used */ +#endif +#ifndef configUSE_CO_ROUTINES + #define configUSE_CO_ROUTINES 0 +#endif +#ifndef configUSE_MUTEXES + #define configUSE_MUTEXES 1 +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW + #define configCHECK_FOR_STACK_OVERFLOW 1 /* 0 is disabling stack overflow. Set it to 1 for Method1 or 2 for Method2 */ +#endif +#ifndef configCHECK_FOR_STACK_OVERFLOW_NAME + #define configCHECK_FOR_STACK_OVERFLOW_NAME FRTOS1_vApplicationStackOverflowHook +#endif +#ifndef configUSE_RECURSIVE_MUTEXES + #define configUSE_RECURSIVE_MUTEXES 1 +#endif +#ifndef configQUEUE_REGISTRY_SIZE + #define configQUEUE_REGISTRY_SIZE 5 +#endif +#ifndef configUSE_QUEUE_SETS + #define configUSE_QUEUE_SETS 0 +#endif +#ifndef configUSE_COUNTING_SEMAPHORES + #define configUSE_COUNTING_SEMAPHORES 1 +#endif +#ifndef configUSE_APPLICATION_TASK_TAG + #define configUSE_APPLICATION_TASK_TAG 0 +#endif +/* Tickless Idle Mode ----------------------------------------------------------*/ +#ifndef configUSE_TICKLESS_IDLE + #define configUSE_TICKLESS_IDLE 0 /* set to 1 for tickless idle mode, 0 otherwise */ +#endif +#ifndef configEXPECTED_IDLE_TIME_BEFORE_SLEEP + #define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2 /* number of ticks must be larger than this to enter tickless idle mode */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK + #define configUSE_TICKLESS_IDLE_DECISION_HOOK 0 /* set to 1 to enable application hook, zero otherwise */ +#endif +#ifndef configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME + #define configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME xEnterTicklessIdle /* function name of decision hook */ +#endif +#ifndef configNUM_THREAD_LOCAL_STORAGE_POINTERS + #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0 /* number of tread local storage pointers, 0 to disable functionality */ +#endif + +#ifndef configMAX_PRIORITIES + #define configMAX_PRIORITIES 6 /* task priorities can be from 0 up to this value-1 */ +#endif +#define configMAX_CO_ROUTINE_PRIORITIES 2 /* co-routine priorities can be from 0 up to this value-1 */ + +/* the following needs to be defined (present) or not (not present)! */ +#define configTASK_RETURN_ADDRESS 0 /* return address of task is zero */ + +#ifndef configRECORD_STACK_HIGH_ADDRESS + #define configRECORD_STACK_HIGH_ADDRESS 1 /* 1: record stack high address for the debugger, 0: do not record stack high address */ +#endif + +/* Software timer definitions. */ +#ifndef configUSE_TIMERS + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_TASK_PRIORITY + #define configUSE_TIMERS 0 /* set to 1 to enable software timers */ +#endif +#ifndef configTIMER_QUEUE_LENGTH + #define configTIMER_QUEUE_LENGTH 10U /* size of queue for the timer task */ +#endif +#ifndef configTIMER_TASK_STACK_DEPTH + #define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE) +#endif +#ifndef INCLUDE_xEventGroupSetBitFromISR + #define INCLUDE_xEventGroupSetBitFromISR 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef INCLUDE_xTimerPendFunctionCall + #define INCLUDE_xTimerPendFunctionCall 0 /* 1: function is included; 0: do not include function */ +#endif +#ifndef configUSE_DAEMON_TASK_STARTUP_HOOK + #define configUSE_DAEMON_TASK_STARTUP_HOOK 0 /* 1: use application specific vApplicationDaemonTaskStartupHook(), 0: do not use hook */ +#endif + +/* Set configUSE_TASK_FPU_SUPPORT to 0 to omit floating point support even +if floating point hardware is otherwise supported by the FreeRTOS port in use. +This constant is not supported by all FreeRTOS ports that include floating +point support. */ +#define configUSE_TASK_FPU_SUPPORT 1 + +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ +#define INCLUDE_vTaskEndScheduler 0 +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskResumeFromISR 1 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_pcTaskGetTaskName 1 +/* -------------------------------------------------------------------- */ +#define INCLUDE_pxTaskGetStackStart (1 && configUSE_SEGGER_SYSTEM_VIEWER_HOOKS) +/* -------------------------------------------------------------------- */ +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* Cortex-M specific definitions. */ + #if configCPU_FAMILY_IS_ARM_M4(configCPU_FAMILY) + #define configPRIO_BITS 4 /* 4 bits/16 priority levels on ARM Cortex M4 (Kinetis K Family) */ + #else + #define configPRIO_BITS 2 /* 2 bits/4 priority levels on ARM Cortex M0+ (Kinetis L Family) */ + #endif + + /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ + #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 + + /* The highest interrupt priority that can be used by any interrupt service + routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + PRIORITY THAN THIS! (higher priorities are lower numeric values on an ARM Cortex-M). */ + #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + + /* Interrupt priorities used by the kernel port layer itself. These are generic + to all Cortex-M ports, and do not rely on any particular library functions. */ + #define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) + + /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ + #define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY<<(8-configPRIO_BITS)) +#elif MCUC1_CONFIG_CPU_IS_RISC_V + #define configKERNEL_INTERRUPT_PRIORITY (7) +#endif + +/* Normal assert() semantics without relying on the provision of an assert.h header file. */ +#define configASSERT(x) if((x)==0) { taskDISABLE_INTERRUPTS(); for( ;; ); } +#if 0 /* version for RISC-V with a debug break: */ +#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); __asm volatile( "ebreak" ); for( ;; ); } +#endif + +/* RISC-V only: If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. + Otherwise set configCLINT_BASE_ADDRESS to 0. + */ +#define configCLINT_BASE_ADDRESS 0x0 + +/*---------------------------------------------------------------------------------------*/ +/* MPU and TrustZone settings */ +#ifndef configENABLE_FPU + #define configENABLE_FPU (0) +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #define configENABLE_MPU (0) +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #define configENABLE_TRUSTZONE (0) +#endif /* configENABLE_TRUSTZONE */ +/*---------------------------------------------------------------------------------------*/ + +/* custom include file: */ +/* #include "CustomFreeRTOSSettings.h */ + + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS_license.txt b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS_license.txt new file mode 100644 index 0000000..a4aa909 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/FreeRTOS_license.txt @@ -0,0 +1,38 @@ +The FreeRTOS kernel is released under the MIT open source license, the text of +which is provided below. + +This license covers the FreeRTOS kernel source files, which are located in the +/FreeRTOS/Source directory of the official FreeRTOS kernel download. It also +covers most of the source files in the demo application projects, which are +located in the /FreeRTOS/Demo directory of the official FreeRTOS download. The +demo projects may also include third party software that is not part of FreeRTOS +and is licensed separately to FreeRTOS. Examples of third party software +includes header files provided by chip or tools vendors, linker scripts, +peripheral drivers, etc. All the software in subdirectories of the /FreeRTOS +directory is either open source or distributed with permission, and is free for +use. For the avoidance of doubt, refer to the comments at the top of each +source file. + + +License text: +------------- + +Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. +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. + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.c new file mode 100644 index 0000000..9d09605 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.c @@ -0,0 +1,242 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HF1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : HardFault +** Version : Component 01.022, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Component to simplify hard faults for ARM (Kinetis, S32K). +** Settings : +** Component name : HF1 +** Contents : +** HardFaultHandler - void HF1_HardFaultHandler(void); +** Deinit - void HF1_Deinit(void); +** Init - void HF1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file HF1.h +** @version 01.00 +** @brief +** Component to simplify hard faults for ARM (Kinetis, S32K). +*/ +/*! +** @addtogroup HF1_module HF1 module documentation +** @{ +*/ + +/* MODULE HF1. */ + +#include "HF1.h" + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +/* +** =================================================================== +** Method : HF1_HandlerC (component HardFault) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/** + * This is called from the HardFaultHandler with a pointer the Fault stack + * as the parameter. We can then read the values from the stack and place them + * into local variables for ease of reading. + * We then read the various Fault Status and Address Registers to help decode + * cause of the fault. + * The function ends with a BKPT instruction to force control back into the debugger + */ +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +void HF1_HandlerC(uint32_t *hardfault_args) +{ + /*lint -save -e550 Symbol not accessed. */ + static volatile unsigned long stacked_r0; + static volatile unsigned long stacked_r1; + static volatile unsigned long stacked_r2; + static volatile unsigned long stacked_r3; + static volatile unsigned long stacked_r12; + static volatile unsigned long stacked_lr; + static volatile unsigned long stacked_pc; + static volatile unsigned long stacked_psr; + static volatile unsigned long _CFSR; + static volatile unsigned long _HFSR; + static volatile unsigned long _DFSR; + static volatile unsigned long _AFSR; + static volatile unsigned long _BFAR; + static volatile unsigned long _MMAR; + stacked_r0 = ((unsigned long)hardfault_args[0]); // http://www.asciiworld.com/-Smiley,20-.html + stacked_r1 = ((unsigned long)hardfault_args[1]); // oooo$$$$$$$$$$$$oooo + stacked_r2 = ((unsigned long)hardfault_args[2]); // oo$$$$$$$$$$$$$$$$$$$$$$$$o + stacked_r3 = ((unsigned long)hardfault_args[3]); // oo$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o o$ $$ o$ + stacked_r12 = ((unsigned long)hardfault_args[4]); // o $ oo o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$o $$ $$ $$o$ + stacked_lr = ((unsigned long)hardfault_args[5]); // oo $ $ "$ o$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$o $$$o$$o$ + stacked_pc = ((unsigned long)hardfault_args[6]); // "$$$$$$o$ o$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$o $$$$$$$$ + stacked_psr = ((unsigned long)hardfault_args[7]); // $$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$ + // $$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$ $$$$$$$$$$$$$$ """$$$ + /* Configurable Fault Status Register */ // "$$$""""$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$ + /* Consists of MMSR, BFSR and UFSR */ // $$$ o$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ "$$$o + _CFSR = (*((volatile unsigned long *)(0xE000ED28))); // o$$" $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$o + // $$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" "$$$$$$ooooo$$$$o + /* Hard Fault Status Register */ // o$$$oooo$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ o$$$$$$$$$$$$$$$$$ + _HFSR = (*((volatile unsigned long *)(0xE000ED2C))); // $$$$$$$$"$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$"""""""" + // """" $$$$ "$$$$$$$$$$$$$$$$$$$$$$$$$$$$" o$$$ + /* Debug Fault Status Register */ // "$$$o """$$$$$$$$$$$$$$$$$$"$$" $$$ + _DFSR = (*((volatile unsigned long *)(0xE000ED30))); // $$$o "$$""$$$$$$"""" o$$$ + // $$$$o o$$$" + /* Auxiliary Fault Status Register */ // "$$$$o o$$$$$$o"$$$$o o$$$$ + _AFSR = (*((volatile unsigned long *)(0xE000ED3C))); // "$$$$$oo ""$$$$o$$$$$o o$$$$"" + // ""$$$$$oooo "$$$o$$$$$$$$$""" + // ""$$$$$$$oo $$$$$$$$$$ + /* Read the Fault Address Registers. */ // """"$$$$$$$$$$$ + /* These may not contain valid values. */ // $$$$$$$$$$$$ + /* Check BFARVALID/MMARVALID to see */ // $$$$$$$$$$" + /* if they are valid values */ // "$$$"" + /* MemManage Fault Address Register */ + _MMAR = (*((volatile unsigned long *)(0xE000ED34))); + /* Bus Fault Address Register */ + _BFAR = (*((volatile unsigned long *)(0xE000ED38))); + +#if 0 /* experimental, seems not to work properly with GDB in KDS V3.2.0 */ +#ifdef __GNUC__ /* might improve stack, see https://www.element14.com/community/message/199113/l/gdb-assisted-debugging-of-hard-faults#199113 */ + __asm volatile ( + "tst lr,#4 \n" /* check which stack pointer we are using */ + "ite eq \n" + "mrseq r0, msp \n" /* use MSP */ + "mrsne r0, psp \n" /* use PSP */ + "mov sp, r0 \n" /* set stack pointer so GDB shows proper stack frame */ + ); +#endif +#endif + __asm("BKPT #0\n") ; /* cause the debugger to stop */ + /*lint -restore */ +} + +/* +** =================================================================== +** Method : HardFaultHandler (component HardFault) +** +** Description : +** Hard Fault Handler +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +__attribute__((naked)) +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT +void HardFault_Handler(void) +#else +void HF1_HardFaultHandler(void) +#endif +{ + __asm volatile ( + ".syntax unified \n" /* needed for the 'adds r1,#2' below */ + " movs r0,#4 \n" /* load bit mask into R0 */ + " mov r1, lr \n" /* load link register into R1 */ + " tst r0, r1 \n" /* compare with bitmask */ + " beq _MSP \n" /* if bitmask is set: stack pointer is in PSP. Otherwise in MSP */ + " mrs r0, psp \n" /* otherwise: stack pointer is in PSP */ + " b _GetPC \n" /* go to part which loads the PC */ + "_MSP: \n" /* stack pointer is in MSP register */ + " mrs r0, msp \n" /* load stack pointer into R0 */ + "_GetPC: \n" /* find out where the hard fault happened */ + " ldr r1,[r0,#24] \n" /* load program counter into R1. R1 contains address of the next instruction where the hard fault happened */ +#if HF1_CONFIG_SETTING_SEMIHOSTING + /* The following code checks if the hard fault is caused by a semihosting BKPT instruction which is "BKPT 0xAB" (opcode: 0xBEAB) + The idea is taken from the MCUXpresso IDE/SDK code, so credits and kudos to the MCUXpresso IDE team! */ + " ldrh r2,[r1] \n" /* load opcode causing the fault */ + " ldr r3,=0xBEAB \n" /* load constant 0xBEAB (BKPT 0xAB) into R3" */ + " cmp r2,r3 \n" /* is it the BKPT 0xAB? */ + " beq _SemihostReturn \n" /* if yes, return from semihosting */ + " b HF1_HandlerC \n" /* if no, dump the register values and halt the system */ + "_SemihostReturn: \n" /* returning from semihosting fault */ + " adds r1,#2 \n" /* r1 points to the semihosting BKPT instruction. Adjust the PC to skip it (2 bytes) */ + " str r1,[r0,#24] \n" /* store back the ajusted PC value to the interrupt stack frame */ + " movs r1,#32 \n" /* need to pass back a return value to emulate a sucessful semihosting operation. 32 is an arbitrary value */ + " str r1,[r0,#0] \n" /* store the return value on the stack frame */ + " bx lr \n" /* return from the exception handler back to the application */ +#else + " b HF1_HandlerC \n" /* decode more information. R0 contains pointer to stack frame */ +#endif + ); +} + +/* +** =================================================================== +** Method : Deinit (component HardFault) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void HF1_Deinit(void) +{ +#if HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SCB_ACTLR &= ~(SCB_ACTLR_DISDEFWBUF_MASK); /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */ + #elif MCUC1_CONFIG_NXP_SDK_USED && MCUC1_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */ + SCnSCB->ACTLR &= ~SCnSCB_ACTLR_DISDEFWBUF_Msk; + #endif +#endif +} + +/* +** =================================================================== +** Method : Init (component HardFault) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void HF1_Init(void) +{ +#if HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SCB_ACTLR |= SCB_ACTLR_DISDEFWBUF_MASK; /* write buffer bit, see https://community.nxp.com/docs/DOC-103810 */ + #elif MCUC1_CONFIG_NXP_SDK_USED && MCUC1_McuLib_CONFIG_CORTEX_M!=7 /* not for M7? */ + SCnSCB->ACTLR |= SCnSCB_ACTLR_DISDEFWBUF_Msk; + #endif +#endif +} + + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* END HF1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.h new file mode 100644 index 0000000..5fba883 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1.h @@ -0,0 +1,123 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HF1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : HardFault +** Version : Component 01.022, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Component to simplify hard faults for ARM (Kinetis, S32K). +** Settings : +** Component name : HF1 +** Contents : +** HardFaultHandler - void HF1_HardFaultHandler(void); +** Deinit - void HF1_Deinit(void); +** Init - void HF1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file HF1.h +** @version 01.00 +** @brief +** Component to simplify hard faults for ARM (Kinetis, S32K). +*/ +/*! +** @addtogroup HF1_module HF1 module documentation +** @{ +*/ + +#ifndef __HF1_H +#define __HF1_H + +/* MODULE HF1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "HF1config.h" /* configuration */ + + + + +void HF1_HardFaultHandler(void); +/* +** =================================================================== +** Method : HardFaultHandler (component HardFault) +** +** Description : +** Hard Fault Handler +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#ifdef __GNUC__ /* 'used' attribute needed for GNU LTO (Link Time Optimization) */ +void HF1_HandlerC(uint32_t *hardfault_args) __attribute__((used)); +#else +void HF1_HandlerC(uint32_t *hardfault_args); +#endif +/* +** =================================================================== +** Method : HF1_HandlerC (component HardFault) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ + +void HF1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component HardFault) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void HF1_Init(void); +/* +** =================================================================== +** Method : Init (component HardFault) +** +** Description : +** Initializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END HF1. */ + +#endif +/* ifndef __HF1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1config.h new file mode 100644 index 0000000..267b405 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HF1config.h @@ -0,0 +1,25 @@ +/** + * \file + * \brief Configuration header file for HardFault + * + * This header file is used to configure settings of the HardFault module. + */ + +#ifndef __HF1_CONFIG_H +#define __HF1_CONFIG_H + +#define HF1_CONFIG_SETTING_HAS_ACTLR (1 || (defined(__CORTEX_M) && __CORTEX_M>=3)) + /*!< 1: Cortex-M3, M4 have Auxiliary Control Register, ACTLR register */ + +#ifndef HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER + #define HF1_CONFIG_SETTING_DISABLE_WRITE_BUFFER (0 && HF1_CONFIG_SETTING_HAS_ACTLR) + /*!< 1: disable write buffer in ACTLR register */ +#endif + +#ifndef HF1_CONFIG_SETTING_SEMIHOSTING + #define HF1_CONFIG_SETTING_SEMIHOSTING (1) + /*!< 1: do not stop in handler with semihosting and no debugger attached. 0: semihosting hardfault will stop target */ +#endif + + +#endif /* __HF1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.c new file mode 100644 index 0000000..0647600 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.c @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HMODE.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : HMODE +** Pin for I/O : ADC0_SE13/TSI0_CH8/PTB3/I2C0_SDA/UART0_CTS_b/UART0_COL_b/FTM0_FLT0 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool HMODE_GetVal(void); +** PutVal - void HMODE_PutVal(bool Val); +** ClrVal - void HMODE_ClrVal(void); +** SetVal - void HMODE_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file HMODE.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup HMODE_module HMODE module documentation +** @{ +*/ + +/* MODULE HMODE. */ + +#include "HMODE.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : HMODE_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool HMODE_GetVal(void) + +** This method is implemented as a macro. See HMODE.h file. ** +*/ + +/* +** =================================================================== +** Method : HMODE_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +/* +void HMODE_PutVal(bool Val) + +** This method is implemented as a macro. See HMODE.h file. ** +*/ + +/* +** =================================================================== +** Method : HMODE_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void HMODE_ClrVal(void) + +** This method is implemented as a macro. See HMODE.h file. ** +*/ + +/* +** =================================================================== +** Method : HMODE_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void HMODE_SetVal(void) + +** This method is implemented as a macro. See HMODE.h file. ** +*/ + +/* END HMODE. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.h new file mode 100644 index 0000000..94f371e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/HMODE.h @@ -0,0 +1,176 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : HMODE.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : HMODE +** Pin for I/O : ADC0_SE13/TSI0_CH8/PTB3/I2C0_SDA/UART0_CTS_b/UART0_COL_b/FTM0_FLT0 +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool HMODE_GetVal(void); +** PutVal - void HMODE_PutVal(bool Val); +** ClrVal - void HMODE_ClrVal(void); +** SetVal - void HMODE_SetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file HMODE.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup HMODE_module HMODE module documentation +** @{ +*/ + +#ifndef __HMODE_H +#define __HMODE_H + +/* MODULE HMODE. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd8.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : HMODE_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define HMODE_GetVal() (BitIoLdd8_GetVal(BitIoLdd8_DeviceData)) + +/* +** =================================================================== +** Method : HMODE_PutVal (component BitIO) +** Description : +** This method writes the new output value. +** Parameters : +** NAME - DESCRIPTION +** Val - Output value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) +** Returns : Nothing +** =================================================================== +*/ +#define HMODE_PutVal(Val) (BitIoLdd8_PutVal(BitIoLdd8_DeviceData, (Val))) + +/* +** =================================================================== +** Method : HMODE_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define HMODE_ClrVal() (BitIoLdd8_ClrVal(BitIoLdd8_DeviceData)) + +/* +** =================================================================== +** Method : HMODE_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define HMODE_SetVal() (BitIoLdd8_SetVal(BitIoLdd8_DeviceData)) + +/* END HMODE. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __HMODE_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/IO_Map.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/IO_Map.h new file mode 100644 index 0000000..cc35b6c --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/IO_Map.h @@ -0,0 +1,79 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : IO_Map.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : IO_Map +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file IO_Map.h +** @version 01.00 +** @brief +** IO_Map.h - implements an IO device's mapping. +** This module contains symbol definitions of all peripheral +** registers and bits. +*/ +/*! +** @addtogroup IO_Map_module IO_Map module documentation +** @{ +*/ + +#ifndef __IO_Map_H +#define __IO_Map_H + +#include "MK20D5.h" + +#endif +/* __IO_Map_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.c new file mode 100644 index 0000000..1485cbc --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.c @@ -0,0 +1,713 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KIN1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : KinetisTools +** Version : Component 01.041, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : KIN1 +** Utility : UTIL1 +** SDK : MCUC1 +** Shell : Enabled +** Shell : CLS1 +** Contents : +** SoftwareReset - void KIN1_SoftwareReset(void); +** UIDGet - uint8_t KIN1_UIDGet(KIN1_UID *uid); +** UIDSame - bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +** UIDtoString - uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +** GetKinetisFamilyString - KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +** GetPC - void* KIN1_GetPC(void); +** GetSP - void* KIN1_GetSP(void); +** SetPSP - void KIN1_SetPSP(void *setval); +** SetLR - void KIN1_SetLR(uint32_t setval); +** InitCycleCounter - void KIN1_InitCycleCounter(void); +** ResetCycleCounter - void KIN1_ResetCycleCounter(void); +** EnableCycleCounter - void KIN1_EnableCycleCounter(void); +** DisableCycleCounter - void KIN1_DisableCycleCounter(void); +** GetCycleCounter - uint32_t KIN1_GetCycleCounter(void); +** ParseCommand - uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const... +** Deinit - void KIN1_Deinit(void); +** Init - void KIN1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KIN1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KIN1_module KIN1 module documentation +** @{ +*/ + +/* MODULE KIN1. */ + +#include "KIN1.h" + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +#include "UTIL1.h" /* various utility functions */ +#if MCUC1_CONFIG_NXP_SDK_2_0_USED + #include "fsl_common.h" + #if MCUC1_CONFIG_CPU_IS_KINETIS + #include "fsl_sim.h" /* system integration module, used for CPU ID */ + #endif +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3 + #include "Cpu.h" /* include CPU related interfaces and defines */ +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K + #include "Cpu.h" /* include CPU related interfaces and defines */ +#elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* include device specific header file for CMSIS inside "KIN1config.h" */ +#endif + +#if MCUC1_CONFIG_CPU_IS_KINETIS +#if MCUC1_CONFIG_CORTEX_M==4 +static const unsigned char *KinetisM4FamilyStrings[] = +{ /* FAMID (3 bits) are used as index */ + (const unsigned char *)"K10 or K12 Family", /* 000 */ + (const unsigned char *)"K20 or K22 Family", /* 001 */ + (const unsigned char *)"K30, K11 or K61 Family", /* 010 */ + (const unsigned char *)"K40 or K21 Family", /* 011 */ + (const unsigned char *)"K60 or K62 Family", /* 100 */ + (const unsigned char *)"K70 Family", /* 101 */ + (const unsigned char *)"Reserved", /* 110 */ + (const unsigned char *)"Reserved" /* 111 */ +}; +#endif + +#if MCUC1_CONFIG_CORTEX_M==0 +static const unsigned char *KinetisM0FamilyStrings[] = +{ /* FAMID (3 bits) are used as index */ + (const unsigned char *)"KL0x", /* 0000 */ + (const unsigned char *)"KL1x", /* 0001 */ + (const unsigned char *)"KL2x", /* 0010 */ + (const unsigned char *)"KL3x", /* 0011 */ + (const unsigned char *)"KL4x", /* 0100 */ + (const unsigned char *)"Reserved", /* 0101 */ + (const unsigned char *)"Reserved", /* 0110 */ + (const unsigned char *)"Reserved" /* 0111 */ +}; +#endif +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +static uint8_t PrintStatus(const CLS1_StdIOType *io) +{ +#if MCUC1_CONFIG_CPU_IS_KINETIS + uint8_t buf[1+(16*5)+1+1]; /* "{0xAA,...0xBB}" */ + uint8_t res; + KIN1_UID uid; +#endif + + CLS1_SendStatusStr((unsigned char*)"KIN1", (unsigned char*)"\r\n", io->stdOut); +#if MCUC1_CONFIG_CPU_IS_KINETIS + res = KIN1_UIDGet(&uid); + if (res==ERR_OK) { + res = KIN1_UIDtoString(&uid, buf, sizeof(buf)); + } + if (res!=ERR_OK) { + UTIL1_strcpy(buf, sizeof(buf), (unsigned char*)"ERROR"); + } + CLS1_SendStatusStr((unsigned char*)" UID", buf, io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); +#endif + CLS1_SendStatusStr((unsigned char*)" Family", (uint8_t*)KIN1_GetKinetisFamilyString(), io->stdOut); + CLS1_SendStr((unsigned char*)"\r\n", io->stdOut); + return ERR_OK; +} +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +static uint8_t PrintHelp(const CLS1_StdIOType *io) +{ + CLS1_SendHelpStr((unsigned char*)"KIN1", (unsigned char*)"Group of KIN1 commands\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" reset", (unsigned char*)"Performs a software reset\r\n", io->stdOut); + CLS1_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut); + return ERR_OK; +} +#endif + +/* +** =================================================================== +** Method : SoftwareReset (component KinetisTools) +** +** Description : +** Performs a reset of the device +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SoftwareReset(void) +{ + /* Generic way to request a reset from software for ARM Cortex */ + /* See https://community.freescale.com/thread/99740 + To write to this register, you must write 0x5FA to the VECTKEY field, otherwise the processor ignores the write. + SYSRESETREQ will cause a system reset asynchronously, so need to wait afterwards. + */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M +#if MCUC1_CONFIG_PEX_SDK_USED + SCB_AIRCR = SCB_AIRCR_VECTKEY(0x5FA) | SCB_AIRCR_SYSRESETREQ_MASK; +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K + S32_SCB->AIRCR = S32_SCB_AIRCR_VECTKEY(0x5FA) | S32_SCB_AIRCR_SYSRESETREQ_MASK; +#else + SCB->AIRCR = (0x5FA<id[i] = 0; + } + if (sizeof(sim_uid_t)>sizeof(KIN1_UID)) { + return ERR_OVERFLOW; + } + /* copy into our own structure, data is right justified */ + for(i=0,j=sizeof(KIN1_UID)-sizeof(sim_uid_t);iid[j] = ((uint8_t*)&tmp)[i]; + } + #else /* not MCUC1_CONFIG_NXP_SDK_2_0_USED */ + #ifdef SIM_UIDMH /* 80 or 128 bit UUID: SIM_UIDMH, SIM_UIDML and SIM_UIDL */ + #ifdef SIM_UIDH + uid->id[0] = (SIM_UIDH>>24)&0xff; + uid->id[1] = (SIM_UIDH>>16)&0xff; + uid->id[2] = (SIM_UIDH>>8)&0xff; + uid->id[3] = SIM_UIDH&0xff; + #else + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + #endif + uid->id[4] = (SIM_UIDMH>>24)&0xff; + uid->id[5] = (SIM_UIDMH>>16)&0xff; + uid->id[6] = (SIM_UIDMH>>8)&0xff; + uid->id[7] = SIM_UIDMH&0xff; + + uid->id[8] = (SIM_UIDML>>24)&0xff; + uid->id[9] = (SIM_UIDML>>16)&0xff; + uid->id[10] = (SIM_UIDML>>8)&0xff; + uid->id[11] = SIM_UIDML&0xff; + + uid->id[12] = (SIM_UIDL>>24)&0xff; + uid->id[13] = (SIM_UIDL>>16)&0xff; + uid->id[14] = (SIM_UIDL>>8)&0xff; + uid->id[15] = SIM_UIDL&0xff; + #elif defined(SIM_UUIDMH) /* KE06Z: SIM_UUIDMH, SIM_UUIDML and SIM_UUIDL */ + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + uid->id[4] = 0; + uid->id[5] = 0; + uid->id[6] = (SIM_UUIDMH>>8)&0xff; + uid->id[7] = SIM_UUIDMH&0xff; + + uid->id[8] = (SIM_UUIDML>>24)&0xff; + uid->id[9] = (SIM_UUIDML>>16)&0xff; + uid->id[10] = (SIM_UUIDML>>8)&0xff; + uid->id[11] = SIM_UUIDML&0xff; + + uid->id[12] = (SIM_UUIDL>>24)&0xff; + uid->id[13] = (SIM_UUIDL>>16)&0xff; + uid->id[14] = (SIM_UUIDL>>8)&0xff; + uid->id[15] = SIM_UUIDL&0xff; + #else /* some devices like the KE02Z only have 64bit UUID: only SIM_UUIDH and SIM_UUIDL */ + uid->id[0] = 0; + uid->id[1] = 0; + uid->id[2] = 0; + uid->id[3] = 0; + uid->id[4] = 0; + uid->id[5] = 0; + uid->id[6] = 0; + uid->id[7] = 0; + uid->id[8] = (SIM_UUIDH>>24)&0xff; + uid->id[9] = (SIM_UUIDH>>16)&0xff; + uid->id[10] = (SIM_UUIDH>>8)&0xff; + uid->id[11] = SIM_UUIDH&0xff; + + uid->id[12] = (SIM_UUIDL>>24)&0xff; + uid->id[13] = (SIM_UUIDL>>16)&0xff; + uid->id[14] = (SIM_UUIDL>>8)&0xff; + uid->id[15] = SIM_UUIDL&0xff; + #endif + #endif /* MCUC1_CONFIG_NXP_SDK_2_0_USED */ + return ERR_OK; +#else + (void)uid; /* not used */ + return ERR_FAILED; +#endif +} + +/* +** =================================================================== +** Method : UIDSame (component KinetisTools) +** +** Description : +** Compares two UID +** Parameters : +** NAME - DESCRIPTION +** * src - Pointer to +** Variable_1 - +** Returns : +** --- - TRUE if the same, FALSE otherwise +** =================================================================== +*/ +/*! + * \brief Compares two UID + * \param src One UID + * \param dst The other UID + * \return TRUE if the two UID's are the same + */ +bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst) +{ + unsigned int i; + + for(i=0; iid[i]!=dst->id[i]) { + return FALSE; /* no match */ + } + } + return TRUE; +} + +/* +** =================================================================== +** Method : UIDtoString (component KinetisTools) +** +** Description : +** Returns the value of the UID as string +** Parameters : +** NAME - DESCRIPTION +** uid - +** * buf - Pointer to +** bufSize - +** Returns : +** --- - Error code +** =================================================================== +*/ +/*! + * \brief Transforms the 80bit UID into a string + * \param id Pointer to the buffer where to store the string + * \param bufSize Size of buffer in bytes + * \return Error code, ERR_OK if everything is ok. + */ +uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize) +{ + unsigned int i; + + UTIL1_strcpy(buf, bufSize, (unsigned char*)"{"); + for(i=0;iid[i]); + if (i>28)&0x3; /* bits 30..28 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM0FamilyStrings)/sizeof(KinetisM0FamilyStrings[0]))) { + return KinetisM0FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M0 Family ID out of bounds!"; + } + #elif defined(SIM_SRSID_FAMID) /* MKE02Z4 defines this, hopefully all other KE too... */ + return (KIN1_ConstCharPtr)"KE0x Family"; /* 0000 only KE0x supported */ + #elif defined(SIM_SDID_FAMID) + int32_t val; + + val = ((SIM->SDID)>>28)&0xF; /* bits 31..28 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM0FamilyStrings)/sizeof(KinetisM0FamilyStrings[0]))) { + return KinetisM0FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M0 Family ID out of bounds!"; + } + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif + #elif MCUC1_CONFIG_CORTEX_M==4 + #ifdef SIM_SDID /* normal Kinetis define this */ + int32_t val; + + val = (SIM_SDID>>4)&0x3; /* bits 6..4 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM4FamilyStrings)/sizeof(KinetisM4FamilyStrings[0]))) { + return KinetisM4FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M4 Family ID out of bounds!"; + } + #elif defined(SIM_SDID_FAMID) + int32_t val; + + val = ((SIM->SDID)>>4)&0x3; /* bits 6..4 */ + if (val>=0 && val<=(int32_t)(sizeof(KinetisM4FamilyStrings)/sizeof(KinetisM4FamilyStrings[0]))) { + return KinetisM4FamilyStrings[val]; + } else { + return (KIN1_ConstCharPtr)"M4 Family ID out of bounds!"; + } + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif + #elif MCUC1_CONFIG_CORTEX_M==7 + return (KIN1_ConstCharPtr)"Cortex-M7"; + #else + #error "Unknown architecture!" + return (KIN1_ConstCharPtr)"ERROR"; + #endif +#elif MCUC1_CONFIG_CPU_IS_NORDIC_NRF + return (KIN1_ConstCharPtr)"Nordic nRF"; +#elif MCUC1_CONFIG_CPU_IS_STM + return (KIN1_ConstCharPtr)"STM32"; +#elif MCUC1_CONFIG_CPU_IS_IMXRT + return (KIN1_ConstCharPtr)"NXP i.MX RT"; +#elif MCUC1_CONFIG_CPU_IS_S32K + return (KIN1_ConstCharPtr)"NXP S32K"; +#elif MCUC1_CONFIG_CPU_IS_LPC55xx + return (KIN1_ConstCharPtr)"NXP LPC55xx"; +#elif MCUC1_CONFIG_CPU_IS_LPC + return (KIN1_ConstCharPtr)"NXP LPC"; +#else + return (KIN1_ConstCharPtr)"UNKNOWN"; +#endif +} + +/* +** =================================================================== +** Method : GetPC (component KinetisTools) +** +** Description : +** returns the program counter +** Parameters : None +** Returns : +** --- - program counter +** =================================================================== +*/ +void* KIN1_GetPC(void) +{ +#ifdef __GNUC__ + void *pc; + + __asm__ __volatile__ ("mov %0, pc" : "=r"(pc)); + return pc; +#else + #warning "only for GCC" + return NULL; +#endif +} + +/* +** =================================================================== +** Method : GetSP (component KinetisTools) +** +** Description : +** returns the stack pointer +** Parameters : None +** Returns : +** --- - stack pointer +** =================================================================== +*/ +void* KIN1_GetSP(void) +{ +#ifdef __GNUC__ + void *sp; + + __asm__ __volatile__ ("mrs %0, msp" : "=r"(sp)); + return sp; +#else + #warning "only for GCC" + return NULL; +#endif +} + +/* +** =================================================================== +** Method : SetPSP (component KinetisTools) +** +** Description : +** sets the process stack pointer +** Parameters : +** NAME - DESCRIPTION +** setval - new PSP value +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SetPSP(void *setval) +{ +#ifdef __GNUC__ + __asm__ volatile ("msr psp, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); + __asm__ volatile ("" ::: "memory"); +#else + #warning "only for GCC implemented" +#endif +} + +/* +** =================================================================== +** Method : SetLR (component KinetisTools) +** +** Description : +** Sets the link register +** Parameters : +** NAME - DESCRIPTION +** setval - new LR value +** Returns : Nothing +** =================================================================== +*/ +void KIN1_SetLR(uint32_t setval) +{ +#ifdef __GNUC__ + __asm__ volatile ("mov lr, %[value]\n\t"::[value]"r"(setval):); + __asm__ volatile ("" ::: "memory"); +#else + #warning "only for GCC" +#endif +} + +/* +** =================================================================== +** Method : InitCycleCounter (component KinetisTools) +** +** Description : +** Initializes the cycle counter, available if the core has a +** DWT (Data Watchpoint and Trace) unit, usually present on +** M3/M4/M7 +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_InitCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : ResetCycleCounter (component KinetisTools) +** +** Description : +** Reset the cycle counter (set it to zero) +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_ResetCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : EnableCycleCounter (component KinetisTools) +** +** Description : +** Enables counting the cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_EnableCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : DisableCycleCounter (component KinetisTools) +** +** Description : +** Disables the cycle counter. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/** +void KIN1_DisableCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : GetCycleCounter (component KinetisTools) +** +** Description : +** Return the current cycle counter value +** Parameters : None +** Returns : +** --- - cycle counter +** =================================================================== +*/ +/** +uint32_t KIN1_GetCycleCounter(void) +{ + ** Implemented as macro in header file +} +*/ + +/* +** =================================================================== +** Method : Deinit (component KinetisTools) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component KinetisTools) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void KIN1_Init(void) +{ + /* Nothing needed */ +} + + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* END KIN1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.h new file mode 100644 index 0000000..8ecc40f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1.h @@ -0,0 +1,394 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : KIN1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : KinetisTools +** Version : Component 01.041, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : KIN1 +** Utility : UTIL1 +** SDK : MCUC1 +** Shell : Enabled +** Shell : CLS1 +** Contents : +** SoftwareReset - void KIN1_SoftwareReset(void); +** UIDGet - uint8_t KIN1_UIDGet(KIN1_UID *uid); +** UIDSame - bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +** UIDtoString - uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +** GetKinetisFamilyString - KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +** GetPC - void* KIN1_GetPC(void); +** GetSP - void* KIN1_GetSP(void); +** SetPSP - void KIN1_SetPSP(void *setval); +** SetLR - void KIN1_SetLR(uint32_t setval); +** InitCycleCounter - void KIN1_InitCycleCounter(void); +** ResetCycleCounter - void KIN1_ResetCycleCounter(void); +** EnableCycleCounter - void KIN1_EnableCycleCounter(void); +** DisableCycleCounter - void KIN1_DisableCycleCounter(void); +** GetCycleCounter - uint32_t KIN1_GetCycleCounter(void); +** ParseCommand - uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const... +** Deinit - void KIN1_Deinit(void); +** Init - void KIN1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file KIN1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup KIN1_module KIN1 module documentation +** @{ +*/ + +#ifndef __KIN1_H +#define __KIN1_H + +/* MODULE KIN1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "KIN1config.h" /* configuration */ + +#include /* for size_t */ +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED + #include "CLS1.h" /* Command line shell */ +#endif + + +#ifndef __BWUserType_KIN1_ConstCharPtr +#define __BWUserType_KIN1_ConstCharPtr + typedef const uint8_t *KIN1_ConstCharPtr; /* Pointer to constant string */ +#endif + + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ + /* DWT (Data Watchpoint and Trace) registers, only exists on ARM Cortex with a DWT unit */ + #define KIN1_DWT_CONTROL (*((volatile uint32_t*)0xE0001000)) + /*!< DWT Control register */ + #define KIN1_DWT_CYCCNTENA_BIT (1UL<<0) + /*!< CYCCNTENA bit in DWT_CONTROL register */ + #define KIN1_DWT_CYCCNT (*((volatile uint32_t*)0xE0001004)) + /*!< DWT Cycle Counter register */ + #define KIN1_DEMCR (*((volatile uint32_t*)0xE000EDFC)) + /*!< DEMCR: Debug Exception and Monitor Control Register */ + #define KIN1_TRCENA_BIT (1UL<<24) + /*!< Trace enable bit in DEMCR register */ +#endif + +typedef struct { + uint8_t id[16]; /* 128 bit ID */ +} KIN1_UID; + +typedef enum { + KIN1_FAMILY_K10_K12, /* K10 or K12 */ + KIN1_FAMILY_K20_K22, /* K10 or K12 */ + KIN1_FAMILY_K30_K11_K61, /* K30, K11 or K61 */ + KIN1_FAMILY_K40_K21, /* K40 or K21 */ + KIN1_FAMILY_K70, /* K70 */ + KIN1_FAMILY_UNKONWN, /* Unknown */ + KIN1_FAMILY_LAST /* Must be last one! */ +} KIN1_FAMILY; + +#define KIN1_PARSE_COMMAND_ENABLED KIN1_CONFIG_PARSE_COMMAND_ENABLED + /*!< set to 1 if method ParseCommand() is present, 0 otherwise */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if KIN1_CONFIG_PARSE_COMMAND_ENABLED +uint8_t KIN1_ParseCommand(const unsigned char* cmd, bool *handled, const CLS1_StdIOType *io); +/* +** =================================================================== +** Method : ParseCommand (component KinetisTools) +** +** Description : +** Shell Command Line parser. Method is only available if Shell +** is enabled in the component properties. +** Parameters : +** NAME - DESCRIPTION +** cmd - Pointer to command string +** * handled - Pointer to variable which tells if +** the command has been handled or not +** * io - Pointer to I/O structure +** Returns : +** --- - Error code +** =================================================================== +*/ +#endif + +void KIN1_SoftwareReset(void); +/* +** =================================================================== +** Method : SoftwareReset (component KinetisTools) +** +** Description : +** Performs a reset of the device +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +uint8_t KIN1_UIDGet(KIN1_UID *uid); +/* +** =================================================================== +** Method : UIDGet (component KinetisTools) +** +** Description : +** Return the 128bit UID of the device +** Parameters : +** NAME - DESCRIPTION +** * uid - Pointer to +** Returns : +** --- - Error code +** =================================================================== +*/ + +bool KIN1_UIDSame(const KIN1_UID *src, const KIN1_UID *dst); +/* +** =================================================================== +** Method : UIDSame (component KinetisTools) +** +** Description : +** Compares two UID +** Parameters : +** NAME - DESCRIPTION +** * src - Pointer to +** Variable_1 - +** Returns : +** --- - TRUE if the same, FALSE otherwise +** =================================================================== +*/ + +uint8_t KIN1_UIDtoString(const KIN1_UID *uid, uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : UIDtoString (component KinetisTools) +** +** Description : +** Returns the value of the UID as string +** Parameters : +** NAME - DESCRIPTION +** uid - +** * buf - Pointer to +** bufSize - +** Returns : +** --- - Error code +** =================================================================== +*/ + +KIN1_ConstCharPtr KIN1_GetKinetisFamilyString(void); +/* +** =================================================================== +** Method : GetKinetisFamilyString (component KinetisTools) +** +** Description : +** Determines the Kinetis Familiy based on SIM_SDID register +** Parameters : None +** Returns : +** --- - String describing the Kinetis Family +** =================================================================== +*/ + +void* KIN1_GetPC(void); +/* +** =================================================================== +** Method : GetPC (component KinetisTools) +** +** Description : +** returns the program counter +** Parameters : None +** Returns : +** --- - program counter +** =================================================================== +*/ + +void* KIN1_GetSP(void); +/* +** =================================================================== +** Method : GetSP (component KinetisTools) +** +** Description : +** returns the stack pointer +** Parameters : None +** Returns : +** --- - stack pointer +** =================================================================== +*/ + +void KIN1_SetPSP(void *setval); +/* +** =================================================================== +** Method : SetPSP (component KinetisTools) +** +** Description : +** sets the process stack pointer +** Parameters : +** NAME - DESCRIPTION +** setval - new PSP value +** Returns : Nothing +** =================================================================== +*/ + +void KIN1_SetLR(uint32_t setval); +/* +** =================================================================== +** Method : SetLR (component KinetisTools) +** +** Description : +** Sets the link register +** Parameters : +** NAME - DESCRIPTION +** setval - new LR value +** Returns : Nothing +** =================================================================== +*/ + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_InitCycleCounter() \ + KIN1_DEMCR |= KIN1_TRCENA_BIT + /*!< TRCENA: Enable trace and debug block DEMCR (Debug Exception and Monitor Control Register */ +/* +** =================================================================== +** Method : InitCycleCounter (component KinetisTools) +** +** Description : +** Initializes the cycle counter, available if the core has a +** DWT (Data Watchpoint and Trace) unit, usually present on +** M3/M4/M7 +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_ResetCycleCounter() \ + KIN1_DWT_CYCCNT = 0 + /*!< Reset cycle counter */ +/* +** =================================================================== +** Method : ResetCycleCounter (component KinetisTools) +** +** Description : +** Reset the cycle counter (set it to zero) +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_EnableCycleCounter() \ + KIN1_DWT_CONTROL |= KIN1_DWT_CYCCNTENA_BIT + /*!< Enable cycle counter */ +/* +** =================================================================== +** Method : EnableCycleCounter (component KinetisTools) +** +** Description : +** Enables counting the cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_DisableCycleCounter() \ + KIN1_DWT_CONTROL &= ~KIN1_DWT_CYCCNTENA_BIT + /*!< Disable cycle counter */ +/* +** =================================================================== +** Method : DisableCycleCounter (component KinetisTools) +** +** Description : +** Disables the cycle counter. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#endif + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3 /* only for Cortex-M3 or higher */ +#define KIN1_GetCycleCounter() \ + KIN1_DWT_CYCCNT + /*!< Read cycle counter register */ +/* +** =================================================================== +** Method : GetCycleCounter (component KinetisTools) +** +** Description : +** Return the current cycle counter value +** Parameters : None +** Returns : +** --- - cycle counter +** =================================================================== +*/ +#endif + +void KIN1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component KinetisTools) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void KIN1_Init(void); +/* +** =================================================================== +** Method : Init (component KinetisTools) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END KIN1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __KIN1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1config.h new file mode 100644 index 0000000..0c875a0 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/KIN1config.h @@ -0,0 +1,29 @@ +/** + * \file + * \brief Configuration header file for Kinetis Tools (or ARM in general) + * + * This header file is used to configure settings of the Kinetis Tools module. + */ + +#ifndef __KIN1_CONFIG_H +#define __KIN1_CONFIG_H + +#if !defined(KIN1_CONFIG_PARSE_COMMAND_ENABLED) + #define KIN1_CONFIG_PARSE_COMMAND_ENABLED (1) + /*!< 1: shell support enabled, 0: otherwise */ +#endif + +#if MCUC1_CONFIG_NXP_SDK_2_0_USED + /* will include system header file in the implementation file */ +#elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3 + /* will include system header file in the implementation file */ +#elif MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* include here the low level CMSIS header files, e.g. with */ + #if MCUC1_CONFIG_CPU_IS_STM32 + #include "stm32f3xx_hal.h" /* header file for STM32F303K8 */ + #elif MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_NORDIC_NRF5 + #include "nrf.h" + #endif +#endif + +#endif /* __KIN1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.c new file mode 100644 index 0000000..443197d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.c @@ -0,0 +1,226 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED1 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED1_On(void); +** Off - void LED1_Off(void); +** Neg - void LED1_Neg(void); +** Get - uint8_t LED1_Get(void); +** Put - void LED1_Put(uint8_t val); +** SetRatio16 - void LED1_SetRatio16(uint16_t ratio); +** Deinit - void LED1_Deinit(void); +** Init - void LED1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED1.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED1_module LED1 module documentation +** @{ +*/ + +/* MODULE LED1. */ + +#include "LED1.h" + +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_On(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Off(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Neg(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ +/* +uint8_t LED1_Get(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ +/* +void LED1_Put(uint8_t val) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED1_Init(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin1_Init(); +#endif + LED1_Off(); +} + +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED1_Deinit(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin1_Deinit(); +#endif +} + +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ +void LED1_SetRatio16(uint16_t ratio) +{ + /* on/off LED: binary on or off */ + if (ratio<(0xffff/2)) { + LED1_Off(); + } else { + LED1_On(); + } +} + +/* END LED1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.h new file mode 100644 index 0000000..7fb69c9 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1.h @@ -0,0 +1,208 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED1 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED1_On(void); +** Off - void LED1_Off(void); +** Neg - void LED1_Neg(void); +** Get - uint8_t LED1_Get(void); +** Put - void LED1_Put(uint8_t val); +** SetRatio16 - void LED1_SetRatio16(uint16_t ratio); +** Deinit - void LED1_Deinit(void); +** Init - void LED1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED1.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED1_module LED1 module documentation +** @{ +*/ + +#ifndef __LED1_H +#define __LED1_H + +/* MODULE LED1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "LED1config.h" /* LED configuration */ +#include "LEDpin1.h" /* interface to pin */ + +#define LED1_ClrVal() LEDpin1_ClrVal() /* put the pin on low level */ +#define LED1_SetVal() LEDpin1_SetVal() /* put the pin on high level */ +#define LED1_SetInput() LEDpin1_SetInput() /* use the pin as input pin */ +#define LED1_SetOutput() LEDpin1_SetOutput() /* use the pin as output pin */ + +#define LED1_PARSE_COMMAND_ENABLED 0 /* set to 1 if method ParseCommand() is present, 0 otherwise */ + + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_On() LEDpin1_ClrVal() +#else + #define LED1_On() LEDpin1_SetVal() +#endif +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_Off() LEDpin1_SetVal() +#else + #define LED1_Off() LEDpin1_ClrVal() +#endif +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED1_Neg() LEDpin1_NegVal() +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_Get() (!(LEDpin1_GetVal())) +#else + #define LED1_Get() LEDpin1_GetVal() +#endif +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ + +void LED1_Init(void); +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED1_Put(val) ((val) ? LED1_On() : LED1_Off()) +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ + +void LED1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void LED1_SetRatio16(uint16_t ratio); +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ + +/* END LED1. */ + +#endif +/* ifndef __LED1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1config.h new file mode 100644 index 0000000..39e4975 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED1config.h @@ -0,0 +1,14 @@ +#ifndef __LED1_CONFIG_H +#define __LED1_CONFIG_H + +#ifndef LED1_CONFIG_USE_GPIO_PIN + #define LED1_CONFIG_USE_GPIO_PIN (1) + /*!< 1: use GPIO pin; 0: use PWM pin */ +#endif + +#ifndef LED1_CONFIG_IS_LOW_ACTIVE + #define LED1_CONFIG_IS_LOW_ACTIVE (1) + /*!< 1: LED is low active (cathode on port side), 0: LED is HIGH active (anode on port side) */ +#endif + +#endif /* __LED1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.c new file mode 100644 index 0000000..60f9b22 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.c @@ -0,0 +1,226 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED2 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED2_On(void); +** Off - void LED2_Off(void); +** Neg - void LED2_Neg(void); +** Get - uint8_t LED2_Get(void); +** Put - void LED2_Put(uint8_t val); +** SetRatio16 - void LED2_SetRatio16(uint16_t ratio); +** Deinit - void LED2_Deinit(void); +** Init - void LED2_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED2.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED2_module LED2 module documentation +** @{ +*/ + +/* MODULE LED2. */ + +#include "LED2.h" + +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED2_On(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED2_Off(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LED2_Neg(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ +/* +uint8_t LED2_Get(void) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ +/* +void LED2_Put(uint8_t val) +{ + *** This method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED2_Init(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin2_Init(); +#endif + LED2_Off(); +} + +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void LED2_Deinit(void) +{ +#if MCUC1_CONFIG_SDK_VERSION_USED != MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + LEDpin2_Deinit(); +#endif +} + +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ +void LED2_SetRatio16(uint16_t ratio) +{ + /* on/off LED: binary on or off */ + if (ratio<(0xffff/2)) { + LED2_Off(); + } else { + LED2_On(); + } +} + +/* END LED2. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.h new file mode 100644 index 0000000..e2ce42f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2.h @@ -0,0 +1,208 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LED2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : LED +** Version : Component 01.077, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** This component implements a universal driver for a single LED. +** Settings : +** Component name : LED2 +** Turned On with initialization : no +** HW Interface : +** On/Off : Enabled +** Pin : LEDpin +** PWM : Disabled +** High Value means ON : no +** Shell : Disabled +** Contents : +** On - void LED2_On(void); +** Off - void LED2_Off(void); +** Neg - void LED2_Neg(void); +** Get - uint8_t LED2_Get(void); +** Put - void LED2_Put(uint8_t val); +** SetRatio16 - void LED2_SetRatio16(uint16_t ratio); +** Deinit - void LED2_Deinit(void); +** Init - void LED2_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file LED2.h +** @version 01.00 +** @brief +** This component implements a universal driver for a single LED. +*/ +/*! +** @addtogroup LED2_module LED2 module documentation +** @{ +*/ + +#ifndef __LED2_H +#define __LED2_H + +/* MODULE LED2. */ +#include "MCUC1.h" /* SDK and API used */ +#include "LED2config.h" /* LED configuration */ +#include "LEDpin2.h" /* interface to pin */ + +#define LED2_ClrVal() LEDpin2_ClrVal() /* put the pin on low level */ +#define LED2_SetVal() LEDpin2_SetVal() /* put the pin on high level */ +#define LED2_SetInput() LEDpin2_SetInput() /* use the pin as input pin */ +#define LED2_SetOutput() LEDpin2_SetOutput() /* use the pin as output pin */ + +#define LED2_PARSE_COMMAND_ENABLED 0 /* set to 1 if method ParseCommand() is present, 0 otherwise */ + + +#if LED2_CONFIG_IS_LOW_ACTIVE + #define LED2_On() LEDpin2_ClrVal() +#else + #define LED2_On() LEDpin2_SetVal() +#endif +/* +** =================================================================== +** Method : On (component LED) +** +** Description : +** This turns the LED on. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED2_CONFIG_IS_LOW_ACTIVE + #define LED2_Off() LEDpin2_SetVal() +#else + #define LED2_Off() LEDpin2_ClrVal() +#endif +/* +** =================================================================== +** Method : Off (component LED) +** +** Description : +** This turns the LED off. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED2_Neg() LEDpin2_NegVal() +/* +** =================================================================== +** Method : Neg (component LED) +** +** Description : +** This negates/toggles the LED +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#if LED2_CONFIG_IS_LOW_ACTIVE + #define LED2_Get() (!(LEDpin2_GetVal())) +#else + #define LED2_Get() LEDpin2_GetVal() +#endif +/* +** =================================================================== +** Method : Get (component LED) +** +** Description : +** This returns logical 1 in case the LED is on, 0 otherwise. +** Parameters : None +** Returns : +** --- - Status of the LED (on or off) +** =================================================================== +*/ + +void LED2_Init(void); +/* +** =================================================================== +** Method : Init (component LED) +** +** Description : +** Performs the LED driver initialization. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define LED2_Put(val) ((val) ? LED2_On() : LED2_Off()) +/* +** =================================================================== +** Method : Put (component LED) +** +** Description : +** Turns the LED on or off. +** Parameters : +** NAME - DESCRIPTION +** val - value to define if the LED has to be on or +** off. +** Returns : Nothing +** =================================================================== +*/ + +void LED2_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component LED) +** +** Description : +** Deinitializes the driver +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void LED2_SetRatio16(uint16_t ratio); +/* +** =================================================================== +** Method : SetRatio16 (component LED) +** +** Description : +** Method to specify the duty cycle. If using a PWM pin, this +** means the duty cycle is set. For On/off pins, values smaller +** 0x7FFF means off, while values greater means on. +** Parameters : +** NAME - DESCRIPTION +** ratio - Ratio value, where 0 means 'off' and +** 0xffff means 'on' +** Returns : Nothing +** =================================================================== +*/ + +/* END LED2. */ + +#endif +/* ifndef __LED2_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2config.h new file mode 100644 index 0000000..ee6ab5b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LED2config.h @@ -0,0 +1,14 @@ +#ifndef __LED2_CONFIG_H +#define __LED2_CONFIG_H + +#ifndef LED2_CONFIG_USE_GPIO_PIN + #define LED2_CONFIG_USE_GPIO_PIN (1) + /*!< 1: use GPIO pin; 0: use PWM pin */ +#endif + +#ifndef LED2_CONFIG_IS_LOW_ACTIVE + #define LED2_CONFIG_IS_LOW_ACTIVE (1) + /*!< 1: LED is low active (cathode on port side), 0: LED is HIGH active (anode on port side) */ +#endif + +#endif /* __LED2_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.c new file mode 100644 index 0000000..da15c5f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.c @@ -0,0 +1,172 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin1 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin1_GetVal(void); +** ClrVal - void LEDpin1_ClrVal(void); +** SetVal - void LEDpin1_SetVal(void); +** NegVal - void LEDpin1_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin1.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin1_module LEDpin1 module documentation +** @{ +*/ + +/* MODULE LEDpin1. */ + +#include "LEDpin1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : LEDpin1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool LEDpin1_GetVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_ClrVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_SetVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin1_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin1_NegVal(void) + +** This method is implemented as a macro. See LEDpin1.h file. ** +*/ + +/* END LEDpin1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.h new file mode 100644 index 0000000..a75ee65 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin1.h @@ -0,0 +1,172 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin1 +** Pin for I/O : PTD0/LLWU_P12/SPI0_PCS0/UART2_RTS_b +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin1_GetVal(void); +** ClrVal - void LEDpin1_ClrVal(void); +** SetVal - void LEDpin1_SetVal(void); +** NegVal - void LEDpin1_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin1.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin1_module LEDpin1 module documentation +** @{ +*/ + +#ifndef __LEDpin1_H +#define __LEDpin1_H + +/* MODULE LEDpin1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd1.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : LEDpin1_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define LEDpin1_GetVal() (BitIoLdd1_GetVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_ClrVal() (BitIoLdd1_ClrVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_SetVal() (BitIoLdd1_SetVal(BitIoLdd1_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin1_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin1_NegVal() (BitIoLdd1_NegVal(BitIoLdd1_DeviceData)) + +/* END LEDpin1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __LEDpin1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.c new file mode 100644 index 0000000..f7d5a59 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.c @@ -0,0 +1,172 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin2 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin2_GetVal(void); +** ClrVal - void LEDpin2_ClrVal(void); +** SetVal - void LEDpin2_SetVal(void); +** NegVal - void LEDpin2_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin2.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin2_module LEDpin2 module documentation +** @{ +*/ + +/* MODULE LEDpin2. */ + +#include "LEDpin2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : LEDpin2_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool LEDpin2_GetVal(void) + +** This method is implemented as a macro. See LEDpin2.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin2_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin2_ClrVal(void) + +** This method is implemented as a macro. See LEDpin2.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin2_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin2_SetVal(void) + +** This method is implemented as a macro. See LEDpin2.h file. ** +*/ + +/* +** =================================================================== +** Method : LEDpin2_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void LEDpin2_NegVal(void) + +** This method is implemented as a macro. See LEDpin2.h file. ** +*/ + +/* END LEDpin2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.h new file mode 100644 index 0000000..1fc812b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/LEDpin2.h @@ -0,0 +1,172 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : LEDpin2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : LEDpin2 +** Pin for I/O : PTD4/LLWU_P14/SPI0_PCS1/UART0_RTS_b/FTM0_CH4/EWM_IN +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Output +** Initialization : +** Init. direction : Output +** Init. value : 0 +** Safe mode : yes +** Optimization for : speed +** Contents : +** GetVal - bool LEDpin2_GetVal(void); +** ClrVal - void LEDpin2_ClrVal(void); +** SetVal - void LEDpin2_SetVal(void); +** NegVal - void LEDpin2_NegVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file LEDpin2.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Output direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup LEDpin2_module LEDpin2 module documentation +** @{ +*/ + +#ifndef __LEDpin2_H +#define __LEDpin2_H + +/* MODULE LEDpin2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd9.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : LEDpin2_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Output direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define LEDpin2_GetVal() (BitIoLdd9_GetVal(BitIoLdd9_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin2_ClrVal (component BitIO) +** Description : +** This method clears (sets to zero) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin2_ClrVal() (BitIoLdd9_ClrVal(BitIoLdd9_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin2_SetVal (component BitIO) +** Description : +** This method sets (sets to one) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin2_SetVal() (BitIoLdd9_SetVal(BitIoLdd9_DeviceData)) + +/* +** =================================================================== +** Method : LEDpin2_NegVal (component BitIO) +** Description : +** This method negates (inverts) the output value. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#define LEDpin2_NegVal() (BitIoLdd9_NegVal(BitIoLdd9_DeviceData)) + +/* END LEDpin2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __LEDpin2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.c new file mode 100644 index 0000000..808912a --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.c @@ -0,0 +1,95 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MCUC1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : McuLibConfig +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Configures the drivers for various SDKs and APIs used. +** Settings : +** Component name : MCUC1 +** SDK : Processor Expert +** Contents : +** Init - void MCUC1_Init(void); +** Deinit - void MCUC1_Deinit(void); +** +** * Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file MCUC1.h +** @version 01.00 +** @brief +** Configures the drivers for various SDKs and APIs used. +*/ +/*! +** @addtogroup MCUC1_module MCUC1 module documentation +** @{ +*/ + +/* MODULE MCUC1. */ + +#include "MCUC1.h" + +/* +** =================================================================== +** Method : Init (component McuLibConfig) +** +** Description : +** Driver initialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void MCUC1_Init(void) +{ + /* nothing to implement */ +} + +/* +** =================================================================== +** Method : Deinit (component McuLibConfig) +** +** Description : +** Driver deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void MCUC1_Deinit(void) +{ + /* nothing to implement */ +} + +/* END MCUC1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.h new file mode 100644 index 0000000..71f0df9 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1.h @@ -0,0 +1,195 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : MCUC1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : McuLibConfig +** Version : Component 01.014, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Configures the drivers for various SDKs and APIs used. +** Settings : +** Component name : MCUC1 +** SDK : Processor Expert +** Contents : +** Init - void MCUC1_Init(void); +** Deinit - void MCUC1_Deinit(void); +** +** * Copyright (c) 2016-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file MCUC1.h +** @version 01.00 +** @brief +** Configures the drivers for various SDKs and APIs used. +*/ +/*! +** @addtogroup MCUC1_module MCUC1 module documentation +** @{ +*/ + +#ifndef __MCUC1_H +#define __MCUC1_H + +/* MODULE MCUC1. */ +#include "MCUC1config.h" /* include configuration header file */ + +#ifdef __cplusplus +extern "C" { +#endif + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #ifndef __IASMARM__ /* not including standard header files if using IAR assembler */ + /* Include shared modules, which are used for whole project */ + #include "PE_Types.h" + #include "PE_Error.h" + #include "PE_Const.h" + #include "IO_Map.h" + #include "Cpu.h" /* include CPU related interfaces and defines */ + #endif +#else /* use non-Processor Expert SDK: generic or silicon vendor SDK */ + /* defines of common types used by Processor Expert, which might not be provided by the SDK */ + #if !(defined(__ICCARM__) || defined(__HIWARE__)) /* Hiware compiler (S08, S12) only supports C89 */ + #include /* uint8_t, int16_t, ... */ + #include /* bool, true, false, ... */ + #endif + + /* boolean values */ + #ifndef FALSE + #define FALSE 0x00u + #endif + #ifndef TRUE + #define TRUE 0x01u + #endif + + /* error codes */ + #define ERR_OK 0x00U /*!< OK */ + #define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ + #define ERR_RANGE 0x02U /*!< Parameter out of range. */ + #define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ + #define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ + #define ERR_MATH 0x05U /*!< Overflow during evaluation. */ + #define ERR_ENABLED 0x06U /*!< Device is enabled. */ + #define ERR_DISABLED 0x07U /*!< Device is disabled. */ + #define ERR_BUSY 0x08U /*!< Device is busy. */ + #define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ + #define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ + #define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ + #define ERR_BUSOFF 0x0CU /*!< Bus not available. */ + #define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ + #define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ + #define ERR_PARITY 0x0FU /*!< Parity error is detected. */ + #define ERR_NOISE 0x10U /*!< Noise error is detected. */ + #define ERR_IDLE 0x11U /*!< Idle error is detected. */ + #define ERR_FAULT 0x12U /*!< Fault error is detected. */ + #define ERR_BREAK 0x13U /*!< Break char is received during communication. */ + #define ERR_CRC 0x14U /*!< CRC error is detected. */ + #define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ + #define ERR_PROTECT 0x16U /*!< Protection error is detected. */ + #define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ + #define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ + #define ERR_COMMON 0x19U /*!< Common error of a device. */ + #define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ + #define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ + #define ERR_QFULL 0x1CU /*!< Queue is full. */ + #define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ + #define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ + #define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ + #define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ + #define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ + #define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ + #define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ + #define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ + #define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ + #define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ + #define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ + #define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ + #define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ + #define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ + #define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ + #define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ + #define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ + #define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ + #define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ + #define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ + #define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ + #define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ + #define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ + #define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ + #define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + + /* Other basic data types */ + typedef signed char int8; + typedef signed short int int16; + typedef signed long int int32; + + typedef unsigned char uint8; + typedef unsigned short int uint16; + typedef unsigned long int uint32; +#endif + + + + + +void MCUC1_Init(void); +/* +** =================================================================== +** Method : Init (component McuLibConfig) +** +** Description : +** Driver initialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void MCUC1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component McuLibConfig) +** +** Description : +** Driver deinitialization method +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END MCUC1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __MCUC1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1config.h new file mode 100644 index 0000000..cbb0957 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/MCUC1config.h @@ -0,0 +1,162 @@ +/** + * \file + * \brief Configuration header file for McuLibConfig + * + * This header file is used to configure settings of the McuLibConfig module. + */ + +#ifndef __MCUC1_CONFIG_H +#define __MCUC1_CONFIG_H + +/* identification of CPU/core used. __CORTEX_M is defined in CMSIS-Core. + Otherwise CPU Family is set automatically by Processor Expert: detected: Kinetis (supported: "Kinetis", "S32K", "HCS08") +*/ +#ifndef MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + #define MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M (1 || defined(__CORTEX_M)) + /*!< 1: ARM Cortex-M family, 0 otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_KINETIS + #define MCUC1_CONFIG_CPU_IS_KINETIS (1 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP Kinetis CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_S32K + #define MCUC1_CONFIG_CPU_IS_S32K (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP S32K CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC + #define MCUC1_CONFIG_CPU_IS_LPC (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP LPC CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_LPC55xx + #define MCUC1_CONFIG_CPU_IS_LP55Cxx (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CPU_IS_LPC) + /*!< 1: NXP LPC55xx CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_CPU_IS_STM32 (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: STM32 ARM Cortex CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_IMXRT + #define MCUC1_CONFIG_CPU_IS_IMXRT (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: NXP i.Mx RT CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_NORDIC_NRF + #define MCUC1_CONFIG_CPU_IS_NORDIC_NRF (0 && MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: Nordic nRF, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_HCS08 + #define MCUC1_CONFIG_CPU_IS_HCS08 (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: HCS08 CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V + #define MCUC1_CONFIG_CPU_IS_RISC_V (0 && !MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + /*!< 1: RISC-V CPU family, 0: otherwise */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY + #define MCUC1_CONFIG_CPU_IS_RISC_V_RV32M1_RI5CY (1 && MCUC1_CONFIG_CPU_IS_RISC_V) + /*!< 1: VEGA Board: RISC-V RV32M1 RI5CY, 0: other core */ +#endif +#ifndef MCUC1_CONFIG_CPU_IS_ESP32 + #ifndef __XTENSA__ + #define __XTENSA__ 0 + #endif + #define MCUC1_CONFIG_CPU_IS_ESP32 (__XTENSA__) + /*!< 1: ESP32 CPU family, 0: otherwise. The ESP32 compiler defines __XTENSA__ with a value of 1 */ +#endif + + +/* identification of Cortex-M core. __FPU_USED can be defined in CMSIS-Core */ +#ifndef MCUC1_CONFIG_CORTEX_M + #define MCUC1_CONFIG_CORTEX_M (4) + /*!< 0: Cortex-M0, 3: M3, 4: M4, 7: M7, 33: M33, -1 otherwise */ +#endif +#if (0 && !defined(MCUC1_CONFIG_FPU_PRESENT) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_PRESENT) && (__FPU_PRESENT==1)) /* __FPU_PRESENT can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_PRESENT (1) +#else + #define MCUC1_CONFIG_FPU_PRESENT (0) +#endif + /*!< 1: floating point unit present, 0: otherwise */ +#if (0 && !defined(MCUC1_CONFIG_FPU_USED) && MCUC1_CONFIG_CORTEX_M!=0) || (defined(__FPU_USED) && (__FPU_USED==1)) /* __FPU_USED can be defined in CMSIS-Core */ + #define MCUC1_CONFIG_FPU_USED (1) +#else + #define MCUC1_CONFIG_FPU_USED (0) +#endif + /*!< 1: using floating point unit, 0: otherwise */ + +/* macro for little and big endianess. ARM is little endian */ +#define MCUC1_CONFIG_CPU_IS_LITTLE_ENDIAN (MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M) + +/* Identifiers used to identify the SDK */ +#define MCUC1_CONFIG_SDK_GENERIC 0 + /*!< using a generic API/SDK */ +#define MCUC1_CONFIG_SDK_PROCESSOR_EXPERT 1 + /*!< using Processor Expert SDK */ +#define MCUC1_CONFIG_SDK_KINETIS_1_3 2 + /*!< using NXP Kinetis SDK V1.3 */ +#define MCUC1_CONFIG_SDK_KINETIS_2_0 3 + /*!< using NXP Kinetis SDK V2.0 */ +#define MCUC1_CONFIG_SDK_MCUXPRESSO_2_0 4 + /*!< using NXP MCUXpresso SDK V2.x, same as Kinetis SDK v2.0 */ +#define MCUC1_CONFIG_SDK_S32K 5 + /*!< SDK for S32K */ +#define MCUC1_CONFIG_SDK_NORDIC_NRF5 6 + /*!< Nordic nRF5 SDK */ + +#ifndef MCUC1_CONFIG_SDK_VERSION_MAJOR + #define MCUC1_CONFIG_SDK_VERSION_MAJOR (2) + /*!< SDK major version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_MINOR + #define MCUC1_CONFIG_SDK_VERSION_MINOR (5) + /*!< SDK minor version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION_BUILD + #define MCUC1_CONFIG_SDK_VERSION_BUILD (0) + /*!< SDK build version number */ +#endif + +#ifndef MCUC1_CONFIG_SDK_VERSION + #define MCUC1_CONFIG_SDK_VERSION (MCUC1_CONFIG_SDK_VERSION_MAJOR*100)+(MCUC1_CONFIG_SDK_VERSION_MINOR*10)+MCUC1_CONFIG_SDK_VERSION_BUILD + /*!< Builds a single number with the SDK version (major, minor, build), e.g. 250 for 2.5.0 */ +#endif + +/* specify the SDK and API used */ +#ifndef MCUC1_CONFIG_SDK_VERSION_USED +#if MCUC1_CONFIG_CPU_IS_ESP32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For ESP32 we are using a generic SDK (actually the IDF one) */ +#elif MCUC1_CONFIG_CPU_IS_STM32 + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_GENERIC + /*!< identify the version of SDK/API used. For STM32 we are using a generic SDK (actually the CubeMX one) */ +#else + #define MCUC1_CONFIG_SDK_VERSION_USED MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + /*!< identify the version of SDK/API used */ +#endif +#endif + + +/* Configuration macro if FreeRTOS is used */ +#ifndef MCUC1_CONFIG_SDK_USE_FREERTOS + #define MCUC1_CONFIG_SDK_USE_FREERTOS (1) + /*!< 1: Use FreeRTOS; 0: no FreeRTOS used */ +#endif + +/* special macro to identify a set of SDKs used */ +#define MCUC1_CONFIG_NXP_SDK_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_1_3) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_S32K) \ + ) + /*!< Using one of the Freescale/NXP SDKs */ + +#define MCUC1_CONFIG_NXP_SDK_2_0_USED ( (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_KINETIS_2_0) \ + || (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_MCUXPRESSO_2_0) \ + ) + /*!< Using Freescale/NXP SDK V2.0 */ + +#define MCUC1_CONFIG_PEX_SDK_USED (MCUC1_CONFIG_SDK_VERSION_USED==MCUC1_CONFIG_SDK_PROCESSOR_EXPERT) + /*!< Using Processor Expert API */ + +#endif /* __MCUC1_CONFIG_H */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Const.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Const.h new file mode 100644 index 0000000..b367ca5 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Const.h @@ -0,0 +1,95 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Const.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PE_Const +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "PE_Const" contains internal definitions +** of the constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Const.h +** @version 01.00 +** @brief +** This component "PE_Const" contains internal definitions +** of the constants. +*/ +/*! +** @addtogroup PE_Const_module PE_Const module documentation +** @{ +*/ + +#ifndef __PE_Const_H +#define __PE_Const_H + + +/* Reset cause constants */ +#define RSTSRC_WAKEUP 0x01U /*!< LLWU module wakeup reset */ +#define RSTSRC_LVD 0x02U /*!< Low-voltage detect reset */ +#define RSTSRC_LOC 0x04U /*!< Loss-of-clock reset */ +#define RSTSRC_LOL 0x08U /*!< Loss-of-lock reset */ +#define RSTSRC_COP 0x20U /*!< Watchdog reset */ +#define RSTSRC_WDOG 0x20U /*!< Watchdog reset */ +#define RSTSRC_PIN 0x40U /*!< External pin reset */ +#define RSTSRC_POR 0x80U /*!< Power-on reset */ +#define RSTSRC_JTAG 0x0100U /*!< JTAG reset pin */ +#define RSTSRC_LOCKUP 0x0200U /*!< Core Lock-up reset */ +#define RSTSRC_SW 0x0400U /*!< Software reset */ +#define RSTSRC_MDM_AP 0x0800U /*!< Reset caused by host debugger system */ +#define RSTSRC_EZPT 0x1000U /*!< EzPort reset */ +#define RSTSRC_SACKERR 0x2000U /*!< Stop Mode Acknowledge Error Reset */ + + +/* Low voltage interrupt cause constants */ +#define LVDSRC_LVD 0x01U /*!< Low voltage detect */ +#define LVDSRC_LVW 0x02U /*!< Low-voltage warning */ + +#endif /* _PE_Const_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Error.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Error.h new file mode 100644 index 0000000..7d37d85 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Error.h @@ -0,0 +1,128 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Error.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PE_Error +** Version : Driver 01.00 +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "PE_Error" contains internal definitions +** of the error constants. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Error.h +** @version 01.00 +** @brief +** This component "PE_Error" contains internal definitions +** of the error constants. +*/ +/*! +** @addtogroup PE_Error_module PE_Error module documentation +** @{ +*/ + +#ifndef __PE_Error_H +#define __PE_Error_H + +#define ERR_OK 0x00U /*!< OK */ +#define ERR_SPEED 0x01U /*!< This device does not work in the active speed mode. */ +#define ERR_RANGE 0x02U /*!< Parameter out of range. */ +#define ERR_VALUE 0x03U /*!< Parameter of incorrect value. */ +#define ERR_OVERFLOW 0x04U /*!< Timer overflow. */ +#define ERR_MATH 0x05U /*!< Overflow during evaluation. */ +#define ERR_ENABLED 0x06U /*!< Device is enabled. */ +#define ERR_DISABLED 0x07U /*!< Device is disabled. */ +#define ERR_BUSY 0x08U /*!< Device is busy. */ +#define ERR_NOTAVAIL 0x09U /*!< Requested value or method not available. */ +#define ERR_RXEMPTY 0x0AU /*!< No data in receiver. */ +#define ERR_TXFULL 0x0BU /*!< Transmitter is full. */ +#define ERR_BUSOFF 0x0CU /*!< Bus not available. */ +#define ERR_OVERRUN 0x0DU /*!< Overrun error is detected. */ +#define ERR_FRAMING 0x0EU /*!< Framing error is detected. */ +#define ERR_PARITY 0x0FU /*!< Parity error is detected. */ +#define ERR_NOISE 0x10U /*!< Noise error is detected. */ +#define ERR_IDLE 0x11U /*!< Idle error is detected. */ +#define ERR_FAULT 0x12U /*!< Fault error is detected. */ +#define ERR_BREAK 0x13U /*!< Break char is received during communication. */ +#define ERR_CRC 0x14U /*!< CRC error is detected. */ +#define ERR_ARBITR 0x15U /*!< A node losts arbitration. This error occurs if two nodes start transmission at the same time. */ +#define ERR_PROTECT 0x16U /*!< Protection error is detected. */ +#define ERR_UNDERFLOW 0x17U /*!< Underflow error is detected. */ +#define ERR_UNDERRUN 0x18U /*!< Underrun error is detected. */ +#define ERR_COMMON 0x19U /*!< Common error of a device. */ +#define ERR_LINSYNC 0x1AU /*!< LIN synchronization error is detected. */ +#define ERR_FAILED 0x1BU /*!< Requested functionality or process failed. */ +#define ERR_QFULL 0x1CU /*!< Queue is full. */ +#define ERR_PARAM_MASK 0x80U /*!< Invalid mask. */ +#define ERR_PARAM_MODE 0x81U /*!< Invalid mode. */ +#define ERR_PARAM_INDEX 0x82U /*!< Invalid index. */ +#define ERR_PARAM_DATA 0x83U /*!< Invalid data. */ +#define ERR_PARAM_SIZE 0x84U /*!< Invalid size. */ +#define ERR_PARAM_VALUE 0x85U /*!< Invalid value. */ +#define ERR_PARAM_RANGE 0x86U /*!< Invalid parameter's range or parameters' combination. */ +#define ERR_PARAM_LOW_VALUE 0x87U /*!< Invalid value (LOW part). */ +#define ERR_PARAM_HIGH_VALUE 0x88U /*!< Invalid value (HIGH part). */ +#define ERR_PARAM_ADDRESS 0x89U /*!< Invalid address. */ +#define ERR_PARAM_PARITY 0x8AU /*!< Invalid parity. */ +#define ERR_PARAM_WIDTH 0x8BU /*!< Invalid width. */ +#define ERR_PARAM_LENGTH 0x8CU /*!< Invalid length. */ +#define ERR_PARAM_ADDRESS_TYPE 0x8DU /*!< Invalid address type. */ +#define ERR_PARAM_COMMAND_TYPE 0x8EU /*!< Invalid command type. */ +#define ERR_PARAM_COMMAND 0x8FU /*!< Invalid command. */ +#define ERR_PARAM_RECIPIENT 0x90U /*!< Invalid recipient. */ +#define ERR_PARAM_BUFFER_COUNT 0x91U /*!< Invalid buffer count. */ +#define ERR_PARAM_ID 0x92U /*!< Invalid ID. */ +#define ERR_PARAM_GROUP 0x93U /*!< Invalid group. */ +#define ERR_PARAM_CHIP_SELECT 0x94U /*!< Invalid chip select. */ +#define ERR_PARAM_ATTRIBUTE_SET 0x95U /*!< Invalid set of attributes. */ +#define ERR_PARAM_SAMPLE_COUNT 0x96U /*!< Invalid sample count. */ +#define ERR_PARAM_CONDITION 0x97U /*!< Invalid condition. */ +#define ERR_PARAM_TICKS 0x98U /*!< Invalid ticks parameter. */ + +#endif /* __PE_Error_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.c new file mode 100644 index 0000000..abb1d63 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.c @@ -0,0 +1,212 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 08:06, # CodeGen: 1 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ + +/* MODULE PE_LDD. */ + +#include "FreeRTOS.h" /* FreeRTOS interface */ +/* {FreeRTOS RTOS Adapter} No RTOS driver includes */ + +#include "PE_LDD.h" +#include "Cpu.h" + +/*lint -esym(765,PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory) Disable MISRA rule (8.10) checking for symbols (PE_PeripheralUsed,LDD_SetClockConfiguration,PE_CpuClockConfigurations,PE_FillMemory). */ + +/* +** =========================================================================== +** Array of initialized device structures of LDD components. +** =========================================================================== +*/ +LDD_TDeviceData *PE_LDD_DeviceDataList[16] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + }; + +/* +** =========================================================================== +** The array of clock frequencies in configured clock configurations. +** =========================================================================== +*/ +/*! The array of clock configurations (frequencies) configured in configured clock configurations of the CPU component. */ +const TCpuClockConfiguration PE_CpuClockConfigurations[CPU_CLOCK_CONFIG_NUMBER] = { + /* Clock configuration 0 */ + { + CPU_CORE_CLK_HZ_CONFIG_0, /*!< Core clock frequency in clock configuration 0 */ + CPU_BUS_CLK_HZ_CONFIG_0, /*!< Bus clock frequency in clock configuration 0 */ + CPU_FLEXBUS_CLK_HZ_CONFIG_0, /*!< Flexbus clock frequency in clock configuration 0 */ + CPU_FLASH_CLK_HZ_CONFIG_0, /*!< FLASH clock frequency in clock configuration 0 */ + CPU_USB_CLK_HZ_CONFIG_0, /*!< USB clock frequency in clock configuration 0 */ + CPU_PLL_FLL_CLK_HZ_CONFIG_0, /*!< PLL/FLL clock frequency in clock configuration 0 */ + CPU_MCGIR_CLK_HZ_CONFIG_0, /*!< MCG internal reference clock frequency in clock configuration 0 */ + CPU_OSCER_CLK_HZ_CONFIG_0, /*!< System OSC external reference clock frequency in clock configuration 0 */ + CPU_ERCLK32K_CLK_HZ_CONFIG_0, /*!< External reference clock 32k frequency in clock configuration 0 */ + CPU_MCGFF_CLK_HZ_CONFIG_0 /*!< MCG fixed frequency clock */ + } +}; + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK20DX128FT5) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len) +{ + register uint8_t *ptr = (uint8_t*)SourceAddressPtr; + + if (len > 0U) { + while (len--) { + *ptr++ = c; + } + } +} + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK20DX128FT5) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress) +{ + bool result = FALSE; + + switch (PrphBaseAddress) { + /* Base address allocated by peripheral(s) PTD */ + case 0x400FF0C0UL: + /* Base address allocated by peripheral(s) PTC */ + case 0x400FF080UL: + /* Base address allocated by peripheral(s) FTM0 */ + case 0x40038000UL: + /* Base address allocated by peripheral(s) PTB */ + case 0x400FF040UL: + /* Base address allocated by peripheral(s) PIT */ + case 0x40037000UL: + /* Base address allocated by peripheral(s) UART0 */ + case 0x4006A000UL: + /* Base address allocated by peripheral(s) FTM1 */ + case 0x40039000UL: + /* Base address allocated by peripheral(s) UART2 */ + case 0x4006C000UL: + result = TRUE; + break; + default: + break; + } + return result; +} + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK20DX128FT5) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration) +{ + (void)ClockConfiguration; /*!< Parameter is not used, suppress unused argument warning */ + /* Just one clock configuration defined in CPU component. */ +} + +/* END PE_LDD. */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.h new file mode 100644 index 0000000..82d21cd --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_LDD.h @@ -0,0 +1,175 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_LDD.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 12:37, # CodeGen: 10 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_LDD.h +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup PE_LDD_module PE_LDD module documentation +** @{ +*/ +#ifndef __PE_LDD_H +#define __PE_LDD_H + +/* MODULE PE_LDD. */ + +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "LED1.h" +#include "LEDpin1.h" +#include "BitIoLdd1.h" +#include "MCUC1.h" +#include "SW_FWD.h" +#include "BitIoLdd2.h" +#include "SW_REV.h" +#include "BitIoLdd3.h" +#include "SW_PEELER.h" +#include "BitIoLdd4.h" +#include "ENC1.h" +#include "BitIoLdd5.h" +#include "PWMA.h" +#include "PwmLdd1.h" +#include "TU1.h" +#include "DIRA.h" +#include "BitIoLdd6.h" +#include "DIRB.h" +#include "BitIoLdd7.h" +#include "PWMB.h" +#include "PwmLdd2.h" +#include "HMODE.h" +#include "BitIoLdd8.h" +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "WAIT1.h" +#include "CLS1.h" +#include "XF1.h" +#include "CS1.h" +#include "LED2.h" +#include "LEDpin2.h" +#include "BitIoLdd9.h" +#include "AS1.h" +#include "ASerialLdd1.h" +#include "HF1.h" +#include "TU2.h" +#include "KIN1.h" +#include "RTT1.h" +#include "AS2.h" +#include "ASerialLdd2.h" +#include "UTIL1.h" + + +/* +** =================================================================== +** Function prototypes +** =================================================================== +*/ + +/* +** =================================================================== +** Method : Cpu_PE_FillMemory (component MK20DX128FT5) +*/ +/*! +** @brief +** Fills a memory area block by a specified value. +** @param +** SourceAddressPtr - Source address pointer. +** @param +** c - A value used to fill a memory block. +** @param +** len - Length of a memory block to fill. +*/ +/* ===================================================================*/ +void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + +/* +** =================================================================== +** Method : Cpu_PE_PeripheralUsed (component MK20DX128FT5) +*/ +/*! +** @brief +** Returns information whether a peripheral is allocated by PEx +** or not. +** @param +** PrphBaseAddress - Base address of a peripheral. +** @return +** TRUE if a peripheral is used by PEx or FALSE if it isn't used. +*/ +/* ===================================================================*/ +bool PE_PeripheralUsed(uint32_t PrphBaseAddress); + +/* +** =================================================================== +** Method : Cpu_LDD_SetClockConfiguration (component MK20DX128FT5) +*/ +/*! +** @brief +** Changes the clock configuration of all LDD components in a +** project. +** @param +** ClockConfiguration - New CPU clock configuration changed by CPU SetClockConfiguration method. +*/ +/* ===================================================================*/ +void LDD_SetClockConfiguration(LDD_TClockConfiguration ClockConfiguration); + +/* END PE_LDD. */ + + +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Types.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Types.h new file mode 100644 index 0000000..018eafe --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PE_Types.h @@ -0,0 +1,2549 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PE_Types.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PE_Types +** Version : Driver 01.01 +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 08:06, # CodeGen: 1 +** Abstract : +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +** Contents : +** No public methods +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PE_Types.h +** @version 01.01 +** @brief +** PE_Types.h - contains definitions of basic types, +** register access macros and hardware specific macros +** which can be used in user application. +*/ +/*! +** @addtogroup PE_Types_module PE_Types module documentation +** @{ +*/ + +#ifndef __PE_Types_H +#define __PE_Types_H + +/* Standard ANSI C types */ +#include + +#ifndef FALSE + #define FALSE 0x00u /* Boolean value FALSE. FALSE is defined always as a zero value. */ +#endif +#ifndef TRUE + #define TRUE 0x01u /* Boolean value TRUE. TRUE is defined always as a non zero value. */ +#endif + +#ifndef NULL + #define NULL 0x00u +#endif + +/* PE types definition */ +#ifndef __cplusplus + #ifndef bool +typedef unsigned char bool; + #endif +#endif +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; +typedef unsigned long long dlong; +typedef unsigned char TPE_ErrCode; +#ifndef TPE_Float +typedef float TPE_Float; +#endif +#ifndef char_t +typedef char char_t; +#endif + +/* Other basic data types */ +typedef signed char int8; +typedef signed short int int16; +typedef signed long int int32; + +typedef unsigned char uint8; +typedef unsigned short int uint16; +typedef unsigned long int uint32; + + +/**********************************************************/ +/* Uniform multiplatform 8-bits peripheral access macros */ +/**********************************************************/ + +/* Enable maskable interrupts */ +#define __EI()\ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm("CPSIE f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + +/* Disable maskable interrupts */ +#define __DI() \ + do {\ + /*lint -save -e950 Disable MISRA rule (1.1) checking. */\ + __asm ("CPSID f");\ + /*lint -restore Enable MISRA rule (1.1) checking. */\ + } while(0) + + + +/* Save status register and disable interrupts */ +#define EnterCritical() \ + do {\ + uint8_t SR_reg_local;\ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "MRS R0, FAULTMASK\n\t" \ + "CPSID f\n\t" \ + "STRB R0, %[output]" \ + : [output] "=m" (SR_reg_local)\ + :: "r0");\ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + if (++SR_lock == 1u) {\ + SR_reg = SR_reg_local;\ + }\ + } while(0) + + +/* Restore status register */ +#define ExitCritical() \ + do {\ + if (--SR_lock == 0u) { \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm ( \ + "ldrb r0, %[input]\n\t"\ + "msr FAULTMASK,r0;\n\t" \ + ::[input] "m" (SR_reg) \ + : "r0"); \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */\ + }\ + } while(0) + + +#define PE_DEBUGHALT() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "BKPT 255") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_NOP() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm( "NOP") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + +#define PE_WFI() \ + /*lint -save -e586 -e950 Disable MISRA rule (2.1,1.1) checking. */\ + __asm("WFI") \ + /*lint -restore Enable MISRA rule (2.1,1.1) checking. */ + + +/* Interrupt definition template */ +#if !defined(PE_ISR) + #define PE_ISR(ISR_name) void __attribute__ ((interrupt)) ISR_name(void) +#endif + +/* Logical Device Drivers (LDD) types */ + +/*! Logical Device Driver API version */ +#define PE_LDD_VERSION 0x0100U + +/* LDD driver states */ +#define PE_LDD_DRIVER_DISABLED_IN_CLOCK_CONFIGURATION 0x01U /*!< LDD driver is disabled in the selected clock configuration */ +#define PE_LDD_DRIVER_DISABLED_BY_USER 0x02U /*!< LDD driver is disabled by the user */ +#define PE_LDD_DRIVER_BUSY 0x04U /*!< LDD driver is busy */ + +/*! Macro to register component device structure */ +#define PE_LDD_RegisterDeviceStructure(ComponentIndex, DeviceStructure) (PE_LDD_DeviceDataList[ComponentIndex] = DeviceStructure) + +/*! Macro to unregister component device structure */ +#define PE_LDD_UnregisterDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex] = NULL) + +/*! Macro to get the component device structure */ +#define PE_LDD_GetDeviceStructure(ComponentIndex) (PE_LDD_DeviceDataList[ComponentIndex]) + +/* +** =========================================================================== +** LDD component ID specifying the component instance in the project. This ID +** is used internally as an index to the array of LDD device structures. +** =========================================================================== +*/ +#define PE_LDD_COMPONENT_BitIoLdd1_ID 0x00U +#define PE_LDD_COMPONENT_BitIoLdd2_ID 0x01U +#define PE_LDD_COMPONENT_BitIoLdd3_ID 0x02U +#define PE_LDD_COMPONENT_BitIoLdd4_ID 0x03U +#define PE_LDD_COMPONENT_BitIoLdd5_ID 0x04U +#define PE_LDD_COMPONENT_TU1_ID 0x05U +#define PE_LDD_COMPONENT_PwmLdd1_ID 0x06U +#define PE_LDD_COMPONENT_BitIoLdd6_ID 0x07U +#define PE_LDD_COMPONENT_BitIoLdd7_ID 0x08U +#define PE_LDD_COMPONENT_PwmLdd2_ID 0x09U +#define PE_LDD_COMPONENT_BitIoLdd8_ID 0x0AU +#define PE_LDD_COMPONENT_RTOSCNTRLDD1_ID 0x0BU +#define PE_LDD_COMPONENT_ASerialLdd1_ID 0x0CU +#define PE_LDD_COMPONENT_BitIoLdd9_ID 0x0DU +#define PE_LDD_COMPONENT_TU2_ID 0x0EU +#define PE_LDD_COMPONENT_ASerialLdd2_ID 0x0FU + +/* +** =================================================================== +** Global HAL types and constants +** =================================================================== +*/ +typedef uint32_t LDD_TPinMask; /*!< Pin mask type. */ +typedef uint16_t LDD_TError; /*!< Error type. */ +typedef uint32_t LDD_TEventMask; /*!< Event mask type. */ +typedef uint8_t LDD_TClockConfiguration; /*!< CPU clock configuration type. */ +typedef void LDD_TDeviceData; /*!< Pointer to private device structure managed and used by HAL components. */ +typedef void* LDD_TDeviceDataPtr; /*!< Obsolete type for backward compatibility. */ +typedef void LDD_TData; /*!< General pointer to data. */ +typedef void LDD_TUserData; /*!< Pointer to this type specifies the user or RTOS specific data will be passed as an event or callback parameter. */ + +/*! Driver operation mode type. */ +typedef enum { + DOM_NONE, + DOM_RUN, + DOM_WAIT, + DOM_SLEEP, + DOM_STOP +} LDD_TDriverOperationMode; + +typedef uint16_t LDD_TDriverState; /*!< Driver state type. */ +typedef void LDD_TCallbackParam; /*!< Pointer to this type specifies the user data to be passed as a callback parameter. */ +typedef void (* LDD_TCallback)(LDD_TCallbackParam *CallbackParam); /*!< Callback type used for definition of callback functions. */ + +extern LDD_TDeviceData *PE_LDD_DeviceDataList[]; /*!< Array of LDD component device structures */ + + +/* Fills a memory area block by a specified value. Function defined in PE_LDD.c */ +extern void PE_FillMemory(register void* SourceAddressPtr, register uint8_t c, register uint32_t len); + + +/* +** =================================================================== +** RTOS specific types and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} RTOS specific definition of type of Ioctl() command constants */ + + +/* +** =================================================================== +** Published RTOS settings and constants +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} No published RTOS settings */ + + +/* +** =================================================================== +** TimerUnit device types and constants +** =================================================================== +*/ +#define LDD_TIMERUNIT_ON_CHANNEL_0 0x01u /*!< OnChannel0 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_1 0x02u /*!< OnChannel1 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_2 0x04u /*!< OnChannel2 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_3 0x08u /*!< OnChannel3 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_4 0x10u /*!< OnChannel4 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_5 0x20u /*!< OnChannel5 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_6 0x40u /*!< OnChannel6 event mask value */ +#define LDD_TIMERUNIT_ON_CHANNEL_7 0x80u /*!< OnChannel7 event mask value */ +#define LDD_TIMERUNIT_ON_COUNTER_RESTART 0x0100u /*!< OnCounterRestart event mask value */ + +/*! Direction of counting */ +typedef enum { + DIR_UP, /*!< UP */ + DIR_DOWN /*!< DOWN */ +} LDD_TimerUnit_TCounterDirection; + +/*! Output action type (flip-flop action on overrun or compare match) */ +typedef enum { + OUTPUT_NONE, /*!< NONE */ + OUTPUT_TOGGLE, /*!< TOGGLE */ + OUTPUT_CLEAR, /*!< CLEAR */ + OUTPUT_SET /*!< SET */ +} LDD_TimerUnit_TOutAction; + +/*! Input edge type */ +typedef enum { + EDGE_NONE, /*!< NONE */ + EDGE_RISING, /*!< RISING */ + EDGE_FALLING, /*!< FALLING */ + EDGE_BOTH /*!< BOTH */ +} LDD_TimerUnit_TEdge; + +typedef float LDD_TimerUnit_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** CMT device types and constants +** =================================================================== +*/ +#define LDD_CMT_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** PPG device types and constants +** =================================================================== +*/ +#define LDD_PPG_ON_END 0x01u /*!< OnEnd event mask value */ + +typedef float LDD_PPG_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** PWM types and constants +** =================================================================== +*/ +#define LDD_PWM_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** Capture types and constants +** =================================================================== +*/ +#define LDD_CAPTURE_ON_CAPTURE 0x01u /*!< OnCapture event mask value */ +#define LDD_CAPTURE_ON_OVERRUN 0x02u /*!< OnOverrun event mask value */ + +/* +** =================================================================== +** TimerInt types and constants +** =================================================================== +*/ +#define LDD_TIMERINT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** TimerOut types and constants +** =================================================================== +*/ +#define LDD_TIMEROUT_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** EventCntr types and constants +** =================================================================== +*/ +#define LDD_EVENTCNTR_ON_END 0x01u /*!< OnEnd event mask value */ + +/* +** =================================================================== +** FreeCntr types and constants +** =================================================================== +*/ +#define LDD_FREECNTR_ON_INTERRUPT 0x01u /*!< OnInterrupt event mask value */ + +/* +** =================================================================== +** RealTime types and constants +** =================================================================== +*/ + +typedef float LDD_RealTime_Tfloat; /*!< Float type */ + +/* +** =================================================================== +** TimeDate types and constants +** =================================================================== +*/ +#define LDD_TIMEDATE_ON_ALARM 0x01u /*!< OnAlarm event mask value */ +#define LDD_TIMEDATE_ON_SECOND 0x02u /*!< OnSecond event mask value */ + +/*!< Time struct */ +typedef struct { + uint16_t Hour; /*!< Hours (0 - 23) */ + uint16_t Min; /*!< Minutes (0 - 59) */ + uint16_t Sec; /*!< Seconds (0 - 59) */ + uint16_t Sec100; /*!< Hundredths of seconds (0 - 99) */ +} LDD_TimeDate_TTimeRec; + +/*!< Date struct */ +typedef struct { + uint16_t Year; /*!< Years (1998 - 2099) */ + uint16_t Month; /*!< Months (1 - 12) */ + uint16_t Day; /*!< Days (1 - 31) */ + uint16_t DayOfWeek; /*!< Day of week (0-Sunday, .. 6-Saturday) */ +} LDD_TimeDate_TDateRec; + +/* +** =================================================================== +** UART device types and constants +** =================================================================== +*/ +#define LDD_SERIAL_RX_PIN 0x01u /*!< Receiver pin mask */ +#define LDD_SERIAL_TX_PIN 0x02u /*!< Transmitter pin mask */ +#define LDD_SERIAL_CTS_PIN 0x04u /*!< CTS pin mask */ +#define LDD_SERIAL_RTS_PIN 0x08u /*!< RTS pin mask */ + +#define LDD_SERIAL_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SERIAL_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SERIAL_ON_BREAK 0x04u /*!< OnBreak event mask */ +#define LDD_SERIAL_ON_TXCOMPLETE 0x08u /*!< OnTxComplete event mask */ +#define LDD_SERIAL_ON_ERROR 0x10u /*!< OnError event mask */ + +#define LDD_SERIAL_RX_OVERRUN 0x01u /*!< Receiver overrun */ +#define LDD_SERIAL_PARITY_ERROR 0x02u /*!< Parity error */ +#define LDD_SERIAL_FRAMING_ERROR 0x04u /*!< Framing error */ +#define LDD_SERIAL_NOISE_ERROR 0x08u /*!< Noise error */ + +typedef uint32_t LDD_SERIAL_TError; /*!< Serial communication error type */ + +typedef uint8_t LDD_SERIAL_TDataWidth; /*!< Bit length type. The number of bits transmitted by one character. */ + +typedef uint16_t LDD_SERIAL_TSize; /*!< Type specifying the length of the data or buffer. */ + +typedef uint8_t LDD_SERIAL_TBaudMode; /*!< Type specifying the baud mode. */ + +/*! Type specifying the parity. */ +typedef enum { + LDD_SERIAL_PARITY_UNDEF, /*!< Undefined parity */ + LDD_SERIAL_PARITY_NONE, /*!< Parity none */ + LDD_SERIAL_PARITY_ODD, /*!< Parity odd */ + LDD_SERIAL_PARITY_EVEN, /*!< Parity even */ + LDD_SERIAL_PARITY_MARK, /*!< Parity mark */ + LDD_SERIAL_PARITY_SPACE /*!< Parity space */ +} LDD_SERIAL_TParity; + +/*! Type specifying the stop bit length. */ +typedef enum { + LDD_SERIAL_STOP_BIT_LEN_UNDEF, /*!< Undefined bit length */ + LDD_SERIAL_STOP_BIT_LEN_1, /*!< 1 bit length */ + LDD_SERIAL_STOP_BIT_LEN_1_5, /*!< 1.5 bit length */ + LDD_SERIAL_STOP_BIT_LEN_2 /*!< 2 bit length */ +} LDD_SERIAL_TStopBitLen; + +/*! Communication statistics */ +typedef struct { + uint32_t ReceivedChars; /*!< Number of received characters */ + uint32_t SentChars; /*!< Number of transmitted characters */ + uint32_t ReceivedBreaks; /*!< Number of received break characters */ + uint32_t ParityErrors; /*!< Number of receiver parity errors */ + uint32_t FramingErrors; /*!< Number of receiver framing errors */ + uint32_t OverrunErrors; /*!< Number of receiver overrun errors */ + uint32_t NoiseErrors; /*!< Number of receiver noise errors */ +} LDD_SERIAL_TStats; + +/*! Type specifying the loop mode operation. */ +typedef enum { + LOOPMODE_UNDEF, /*!< Undefined loop mode */ + LOOPMODE_NORMAL, /*!< Normal operation */ + LOOPMODE_AUTO_ECHO, /*!< Auto echo mode */ + LOOPMODE_LOCAL_LOOPBACK, /*!< Local loopback mode */ + LOOPMODE_REMOTE_LOOPBACK /*!< Remote loopback mode */ +} LDD_SERIAL_TLoopMode; + + +/* +** =================================================================== +** ADC device types and constants +** =================================================================== +*/ + +#define LDD_ADC_CHANNEL_0_PIN 0x01u /*!< Channel 0 pin mask */ +#define LDD_ADC_CHANNEL_1_PIN 0x02u /*!< Channel 1 pin mask */ +#define LDD_ADC_CHANNEL_2_PIN 0x04u /*!< Channel 2 pin mask */ +#define LDD_ADC_CHANNEL_3_PIN 0x08u /*!< Channel 3 pin mask */ +#define LDD_ADC_CHANNEL_4_PIN 0x10u /*!< Channel 4 pin mask */ +#define LDD_ADC_CHANNEL_5_PIN 0x20u /*!< Channel 5 pin mask */ +#define LDD_ADC_CHANNEL_6_PIN 0x40u /*!< Channel 6 pin mask */ +#define LDD_ADC_CHANNEL_7_PIN 0x80u /*!< Channel 7 pin mask */ +#define LDD_ADC_CHANNEL_8_PIN 0x0100u /*!< Channel 8 pin mask */ +#define LDD_ADC_CHANNEL_9_PIN 0x0200u /*!< Channel 9 pin mask */ +#define LDD_ADC_CHANNEL_10_PIN 0x0400u /*!< Channel 10 pin mask */ +#define LDD_ADC_CHANNEL_11_PIN 0x0800u /*!< Channel 11 pin mask */ +#define LDD_ADC_CHANNEL_12_PIN 0x1000u /*!< Channel 12 pin mask */ +#define LDD_ADC_CHANNEL_13_PIN 0x2000u /*!< Channel 13 pin mask */ +#define LDD_ADC_CHANNEL_14_PIN 0x4000u /*!< Channel 14 pin mask */ +#define LDD_ADC_CHANNEL_15_PIN 0x8000u /*!< Channel 15 pin mask */ +#define LDD_ADC_CHANNEL_16_PIN 0x00010000u /*!< Channel 16 pin mask */ +#define LDD_ADC_CHANNEL_17_PIN 0x00020000u /*!< Channel 17 pin mask */ +#define LDD_ADC_CHANNEL_18_PIN 0x00040000u /*!< Channel 18 pin mask */ +#define LDD_ADC_CHANNEL_19_PIN 0x00080000u /*!< Channel 19 pin mask */ +#define LDD_ADC_CHANNEL_20_PIN 0x00100000u /*!< Channel 20 pin mask */ +#define LDD_ADC_CHANNEL_21_PIN 0x00200000u /*!< Channel 21 pin mask */ +#define LDD_ADC_CHANNEL_22_PIN 0x00400000u /*!< Channel 22 pin mask */ +#define LDD_ADC_CHANNEL_23_PIN 0x00800000u /*!< Channel 23 pin mask */ +#define LDD_ADC_CHANNEL_24_PIN 0x01000000u /*!< Channel 24 pin mask */ +#define LDD_ADC_CHANNEL_25_PIN 0x02000000u /*!< Channel 25 pin mask */ +#define LDD_ADC_CHANNEL_26_PIN 0x04000000u /*!< Channel 26 pin mask */ +#define LDD_ADC_CHANNEL_27_PIN 0x08000000u /*!< Channel 27 pin mask */ +#define LDD_ADC_CHANNEL_28_PIN 0x10000000u /*!< Channel 28 pin mask */ +#define LDD_ADC_CHANNEL_29_PIN 0x20000000u /*!< Channel 29 pin mask */ +#define LDD_ADC_CHANNEL_30_PIN 0x40000000u /*!< Channel 30 pin mask */ +#define LDD_ADC_CHANNEL_31_PIN 0x80000000u /*!< Channel 31 pin mask */ +#define LDD_ADC_CHANNEL_32_PIN 0x01u /*!< Channel 32 pin mask */ +#define LDD_ADC_CHANNEL_33_PIN 0x02u /*!< Channel 33 pin mask */ +#define LDD_ADC_CHANNEL_34_PIN 0x04u /*!< Channel 34 pin mask */ +#define LDD_ADC_CHANNEL_35_PIN 0x08u /*!< Channel 35 pin mask */ +#define LDD_ADC_CHANNEL_36_PIN 0x10u /*!< Channel 36 pin mask */ +#define LDD_ADC_CHANNEL_37_PIN 0x20u /*!< Channel 37 pin mask */ +#define LDD_ADC_CHANNEL_38_PIN 0x40u /*!< Channel 38 pin mask */ +#define LDD_ADC_CHANNEL_39_PIN 0x80u /*!< Channel 39 pin mask */ +#define LDD_ADC_CHANNEL_40_PIN 0x0100u /*!< Channel 40 pin mask */ +#define LDD_ADC_CHANNEL_41_PIN 0x0200u /*!< Channel 41 pin mask */ +#define LDD_ADC_CHANNEL_42_PIN 0x0400u /*!< Channel 42 pin mask */ +#define LDD_ADC_CHANNEL_43_PIN 0x0800u /*!< Channel 43 pin mask */ +#define LDD_ADC_CHANNEL_44_PIN 0x1000u /*!< Channel 44 pin mask */ +#define LDD_ADC_CHANNEL_45_PIN 0x2000u /*!< Channel 45 pin mask */ +#define LDD_ADC_CHANNEL_46_PIN 0x4000u /*!< Channel 46 pin mask */ +#define LDD_ADC_CHANNEL_47_PIN 0x8000u /*!< Channel 47 pin mask */ +#define LDD_ADC_CHANNEL_48_PIN 0x00010000u /*!< Channel 48 pin mask */ +#define LDD_ADC_CHANNEL_49_PIN 0x00020000u /*!< Channel 49 pin mask */ +#define LDD_ADC_CHANNEL_50_PIN 0x00040000u /*!< Channel 50 pin mask */ +#define LDD_ADC_CHANNEL_51_PIN 0x00080000u /*!< Channel 51 pin mask */ +#define LDD_ADC_CHANNEL_52_PIN 0x00100000u /*!< Channel 52 pin mask */ +#define LDD_ADC_CHANNEL_53_PIN 0x00200000u /*!< Channel 53 pin mask */ +#define LDD_ADC_CHANNEL_54_PIN 0x00400000u /*!< Channel 54 pin mask */ +#define LDD_ADC_CHANNEL_55_PIN 0x00800000u /*!< Channel 55 pin mask */ +#define LDD_ADC_CHANNEL_56_PIN 0x01000000u /*!< Channel 56 pin mask */ +#define LDD_ADC_CHANNEL_57_PIN 0x02000000u /*!< Channel 57 pin mask */ +#define LDD_ADC_CHANNEL_58_PIN 0x04000000u /*!< Channel 58 pin mask */ +#define LDD_ADC_CHANNEL_59_PIN 0x08000000u /*!< Channel 59 pin mask */ +#define LDD_ADC_CHANNEL_60_PIN 0x10000000u /*!< Channel 60 pin mask */ +#define LDD_ADC_CHANNEL_61_PIN 0x20000000u /*!< Channel 61 pin mask */ +#define LDD_ADC_CHANNEL_62_PIN 0x40000000u /*!< Channel 62 pin mask */ +#define LDD_ADC_CHANNEL_63_PIN 0x80000000u /*!< Channel 63 pin mask */ + +#define LDD_ADC_TRIGGER_0_PIN 0x01u /*!< Trigger 0 pin mask */ +#define LDD_ADC_TRIGGER_1_PIN 0x02u /*!< Trigger 1 pin mask */ + +#define LDD_ADC_LOW_VOLT_REF_PIN 0x01u /*!< Low voltage reference pin mask */ +#define LDD_ADC_HIGH_VOLT_REF_PIN 0x02u /*!< High voltage reference pin mask */ + +#define LDD_ADC_ON_MEASUREMENT_COMPLETE 0x40u /*!< OnMeasurementComplete event mask */ +#define LDD_ADC_ON_ERROR 0x80u /*!< OnError event mask */ + +#define LDD_ADC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef uint32_t LDD_ADC_TErrorMask; /*!< ADC error type */ + +/*! Structure pins for pin connection method */ +typedef struct { + uint32_t Channel0_31PinMask; /*!< Channel pin mask for channels 0 through 31 */ + uint32_t Channel32_63PinMask; /*!< Channel pin mask for channels 32 through 63 */ + uint16_t TriggerPinMask; /*!< Trigger pin mask */ + uint8_t VoltRefPinMask; /*!< Voltage reference pin mask */ +} LDD_ADC_TPinMask; + +/*! Structure used to describing one sample */ +typedef struct { + uint8_t ChannelIdx; /*!< Channel index */ +} LDD_ADC_TSample; + +/*! Type specifying the ADC compare mode */ +typedef enum { + LDD_ADC_LESS_THAN = 0x00u, /*!< Compare true if the result is less than the Low compare value */ + LDD_ADC_GREATER_THAN_OR_EQUAL = 0x01u, /*!< Compare true if the result is greater than or equal to Low compare value */ + LDD_ADC_INSIDE_RANGE_INCLUSIVE = 0x02u, /*!< Compare true if the result is greater than or equal to Low compare value and the result is less than or equal to High compare value */ + LDD_ADC_INSIDE_RANGE_NOT_INCLUSIVE = 0x03u, /*!< Compare true if the result is greater than Low compare value and the result is less than High compare value */ + LDD_ADC_OUTSIDE_RANGE_INCLUSIVE = 0x04u, /*!< Compare true if the result is less than or equal to Low compare value or the result is greater than or equal to High compare value */ + LDD_ADC_OUTSIDE_RANGE_NOT_INCLUSIVE = 0x05u /*!< Compare true if the result is less than Low compare value or the result is greater than High compare value */ +} LDD_ADC_TCompareMode; + +/* +** =================================================================== +** I2C device types and constants +** =================================================================== +*/ + +#define LDD_I2C_SDA_PIN 0x01u /*!< SDA pin mask */ +#define LDD_I2C_SCL_PIN 0x02u /*!< SCL pin mask */ + +#define LDD_I2C_ON_MASTER_BLOCK_SENT 0x0001u /*!< OnMasterBlockSent event mask */ +#define LDD_I2C_ON_MASTER_BLOCK_RECEIVED 0x0002u /*!< OnMasterBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_SENT 0x0004u /*!< OnSlaveBlockSent event mask */ +#define LDD_I2C_ON_SLAVE_BLOCK_RECEIVED 0x0008u /*!< OnSlaveBlockReceived event mask */ +#define LDD_I2C_ON_SLAVE_TX_REQUEST 0x0010u /*!< OnSlaveTxRequest event mask */ +#define LDD_I2C_ON_SLAVE_RX_REQUEST 0x0020u /*!< OnSlaveRxRequest event mask */ +#define LDD_I2C_ON_ERROR 0x0040u /*!< OnError event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_CALL_ADDR 0x0080u /*!< OnSlaveSMBusCallAddr event mask */ +#define LDD_I2C_ON_SLAVE_SM_BUS_ALERT_RESPONSE 0x0100u /*!< OnSlaveSMBusAlertResponse event mask */ +#define LDD_I2C_ON_SLAVE_GENERAL_CALL_ADDR 0x0200u /*!< OnSlaveGeneralCallAddr event mask */ +#define LDD_I2C_ON_MASTER_BYTE_RECEIVED 0x0400u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_SLAVE_BYTE_RECEIVED 0x0800u /*!< OnMasterByteReceived event mask */ +#define LDD_I2C_ON_BUS_START_DETECTED 0x1000u /*!< OnBusStartDetected event mask */ +#define LDD_I2C_ON_BUS_STOP_DETECTED 0x2000u /*!< OnBusStopDetected event mask */ + +#define LDD_I2C_SLAVE_TX_UNDERRUN 0x0001u /*!< SlaveTxUnderrun error mask */ +#define LDD_I2C_SLAVE_RX_OVERRUN 0x0002u /*!< SlaveRxOverrun error mask */ +#define LDD_I2C_ARBIT_LOST 0x0004u /*!< ArbitLost error mask */ +#define LDD_I2C_MASTER_NACK 0x0008u /*!< MasterNACK error mask */ +#define LDD_I2C_SCL_LOW_TIMEOUT 0x0010u /*!< SCLLowTimeout error mask */ +#define LDD_I2C_SDA_LOW_TIMEOUT 0x0020u /*!< SDALowTimeout error mask */ +#define LDD_I2C_SLAVE_NACK 0x0040u /*!< SlaveNACK error mask */ + +typedef uint16_t LDD_I2C_TSize; /*!< Type specifying the length of the data or buffer. */ +typedef uint16_t LDD_I2C_TAddr; /*!< Type specifying the address variable */ +typedef uint16_t LDD_I2C_TErrorMask; /*!< Type specifying the error mask type. */ +typedef bool LDD_I2C_TMode; /*!< Type specifynng the Actual operating mode */ + +/*! Type specifying the address type */ +typedef enum { + LDD_I2C_ADDRTYPE_7BITS, /*!< 7 bits address */ + LDD_I2C_ADDRTYPE_10BITS, /*!< 10 bits address */ + LDD_I2C_ADDRTYPE_GENERAL_CALL /*!< General call address */ +} LDD_I2C_TAddrType; + +/*! Type specifying generate the stop condition */ +typedef enum { + LDD_I2C_NO_SEND_STOP, /*!< Do not send stop signal */ + LDD_I2C_SEND_STOP /*!< Send stop signal */ +} LDD_I2C_TSendStop; + +/*! Type specifying the I2C state of BUS. */ +typedef enum { + LDD_I2C_BUSY, /*!< The bus is busy */ + LDD_I2C_IDLE /*!< The bus is idle */ +} LDD_I2C_TBusState; + +/*! Type specifying the I2C byte acknowledge response. */ +typedef enum { + LDD_I2C_ACK_BYTE, /*!< Byte acknowledged */ + LDD_I2C_NACK_BYTE /*!< Byte not acknowledged */ +} LDD_I2C_TAckType; + +/*! Communication statistics */ +typedef struct { + uint32_t MasterSentChars; /*!< Number of master transmitted characters. */ + uint32_t MasterReceivedChars; /*!< Number of master received characters. */ + uint32_t MasterNacks; /*!< Number of no acknowledges. */ + uint32_t ArbitLost; /*!< Number of lost the bus arbitration. */ + uint32_t SlaveSentChars; /*!< Number of slave transmitted characters. */ + uint32_t SlaveReceivedChars; /*!< Number of slave received characters. */ + uint32_t SlaveTxUnderrun; /*!< Number of slave underrun. */ + uint32_t SlaveRxOverrun; /*!< Number of slave overrun. */ + uint32_t SlaveGeneralCallAddr; /*!< Number of a general call address. */ + uint32_t SlaveSmBusCallAddr; /*!< Number of a SMBus call address. */ + uint32_t SlaveSmBusAlertResponse; /*!< Number of slave SMBus alert response received. */ + uint32_t SCLLowTimeout; /*!< Number of SCL low timeout occur. */ + uint32_t SDALowTimeout; /*!< Number of SCL low timeout occur. */ +} LDD_I2C_TStats; + + +/* +** =================================================================== +** SegLCD device types and constants +** =================================================================== +*/ + +#define LDD_SEGLCD_ON_FRAME_FREQUENCY 0x0001u /*!< OnFrameFrequency event mask */ +#define LDD_SEGLCD_ON_FAULT_DETECT_COMPLETE 0x0002u /*!< OnFaultDetectComplete event mask */ + +typedef uint8_t LDD_SegLCD_TPinIndex; /*!< Type specifying the segment LCD pin index variable */ +typedef uint8_t LDD_SegLCD_TFrontplaneData; /*!< Type specifying the frontplane/backplane segment variable */ +typedef uint8_t LDD_SegLCD_TFaultValue; /*!< Type specifying the frontplane/backplane segment variable */ + +/*! Types specifying the segment LCD blinking. */ +typedef enum { + LDD_SEGLCD_BLINK_OFF, /*!< Disables display blinking */ + LDD_SEGLCD_BLINK_ALL, /*!< Display blank during the blink period */ + LDD_SEGLCD_BLINK_ALL_ALTERNATE /*!< Blinking between alternate backplane */ +} LDD_SegLCD_TBlinking; + +/*! Segment LCD blank state type. */ +typedef enum { + LDD_SEGLCD_BLANK_STATE, /*!< Blank display mode */ + LDD_SEGLCD_NORMAL_STATE, /*!< Normal display mode */ + LDD_SEGLCD_ALTERNATE_STATE /*!< Alternate display mode */ +} LDD_SegLCD_TSetBlank; + +/*! Segment LCD pin type (frontplane/backplane) */ +typedef enum { + LDD_SEGLCD_BACKPLANE_PIN, /*!< Backplane pin */ + LDD_SEGLCD_FRONTPLANE_PIN /*!< Frontplane pin */ +} LDD_SegLCD_TPinType; + + +/* +** =================================================================== +** GPIO device types and constants +** =================================================================== +*/ + +#define LDD_GPIO_PIN_0 0x01u /*!< Pin 0 inside the port */ +#define LDD_GPIO_PIN_1 0x02u /*!< Pin 1 inside the port */ +#define LDD_GPIO_PIN_2 0x04u /*!< Pin 2 inside the port */ +#define LDD_GPIO_PIN_3 0x08u /*!< Pin 3 inside the port */ +#define LDD_GPIO_PIN_4 0x10u /*!< Pin 4 inside the port */ +#define LDD_GPIO_PIN_5 0x20u /*!< Pin 5 inside the port */ +#define LDD_GPIO_PIN_6 0x40u /*!< Pin 6 inside the port */ +#define LDD_GPIO_PIN_7 0x80u /*!< Pin 7 inside the port */ +#define LDD_GPIO_PIN_8 0x0100u /*!< Pin 8 inside the port */ +#define LDD_GPIO_PIN_9 0x0200u /*!< Pin 9 inside the port */ +#define LDD_GPIO_PIN_10 0x0400u /*!< Pin 10 inside the port */ +#define LDD_GPIO_PIN_11 0x0800u /*!< Pin 11 inside the port */ +#define LDD_GPIO_PIN_12 0x1000u /*!< Pin 12 inside the port */ +#define LDD_GPIO_PIN_13 0x2000u /*!< Pin 13 inside the port */ +#define LDD_GPIO_PIN_14 0x4000u /*!< Pin 14 inside the port */ +#define LDD_GPIO_PIN_15 0x8000u /*!< Pin 15 inside the port */ +#define LDD_GPIO_PIN_16 0x00010000u /*!< Pin 16 inside the port */ +#define LDD_GPIO_PIN_17 0x00020000u /*!< Pin 17 inside the port */ +#define LDD_GPIO_PIN_18 0x00040000u /*!< Pin 18 inside the port */ +#define LDD_GPIO_PIN_19 0x00080000u /*!< Pin 19 inside the port */ +#define LDD_GPIO_PIN_20 0x00100000u /*!< Pin 20 inside the port */ +#define LDD_GPIO_PIN_21 0x00200000u /*!< Pin 21 inside the port */ +#define LDD_GPIO_PIN_22 0x00400000u /*!< Pin 22 inside the port */ +#define LDD_GPIO_PIN_23 0x00800000u /*!< Pin 23 inside the port */ +#define LDD_GPIO_PIN_24 0x01000000u /*!< Pin 24 inside the port */ +#define LDD_GPIO_PIN_25 0x02000000u /*!< Pin 25 inside the port */ +#define LDD_GPIO_PIN_26 0x04000000u /*!< Pin 26 inside the port */ +#define LDD_GPIO_PIN_27 0x08000000u /*!< Pin 27 inside the port */ +#define LDD_GPIO_PIN_28 0x10000000u /*!< Pin 28 inside the port */ +#define LDD_GPIO_PIN_29 0x20000000u /*!< Pin 29 inside the port */ +#define LDD_GPIO_PIN_30 0x40000000u /*!< Pin 30 inside the port */ +#define LDD_GPIO_PIN_31 0x80000000u /*!< Pin 31 inside the port */ + +#define LDD_GPIO_ON_PORT_EVENT 0x01u /*!< OnPortEvent event mask */ + +typedef uint32_t LDD_GPIO_TBitField; /*!< Abstract type specifying the bit field within the port. */ + +/*! Defines condition when event is invoked. */ +typedef enum { + LDD_GPIO_DISABLED = 0x00u, /*!< Event doesn't invoke */ + LDD_GPIO_LOW = 0x00080000u, /*!< Event when logic zero */ + LDD_GPIO_HIGH = 0x000C0000u, /*!< Event when logic one */ + LDD_GPIO_RISING = 0x00090000u, /*!< Event on rising edge */ + LDD_GPIO_FALLING = 0x000A0000u, /*!< Event on falling edge */ + LDD_GPIO_BOTH = 0x000B0000u /*!< Event on rising and falling edge */ +} LDD_GPIO_TEventCondition; /*!< Defines condition when event is invoked. */ + +#define LDD_GPIO_EVENT_CONDITIONS_MASK 0x000F0000u + +/* +** =================================================================== +** BITSIO device types and constants +** =================================================================== +*/ +#define LDD_BITSIO_PIN_0 0x01U /*!< Pin 0 inside pin list of component */ +#define LDD_BITSIO_PIN_1 0x02U /*!< Pin 1 inside pin list of component */ +#define LDD_BITSIO_PIN_2 0x04U /*!< Pin 2 inside pin list of component */ +#define LDD_BITSIO_PIN_3 0x08U /*!< Pin 3 inside pin list of component */ +#define LDD_BITSIO_PIN_4 0x10U /*!< Pin 4 inside pin list of component */ +#define LDD_BITSIO_PIN_5 0x20U /*!< Pin 5 inside pin list of component */ +#define LDD_BITSIO_PIN_6 0x40U /*!< Pin 6 inside pin list of component */ +#define LDD_BITSIO_PIN_7 0x80U /*!< Pin 7 inside pin list of component */ +#define LDD_BITSIO_PIN_8 0x0100U /*!< Pin 8 inside pin list of component */ +#define LDD_BITSIO_PIN_9 0x0200U /*!< Pin 9 inside pin list of component */ +#define LDD_BITSIO_PIN_10 0x0400U /*!< Pin 10 inside pin list of component */ +#define LDD_BITSIO_PIN_11 0x0800U /*!< Pin 11 inside pin list of component */ +#define LDD_BITSIO_PIN_12 0x1000U /*!< Pin 12 inside pin list of component */ +#define LDD_BITSIO_PIN_13 0x2000U /*!< Pin 13 inside pin list of component */ +#define LDD_BITSIO_PIN_14 0x4000U /*!< Pin 14 inside pin list of component */ +#define LDD_BITSIO_PIN_15 0x8000U /*!< Pin 15 inside pin list of component */ +#define LDD_BITSIO_PIN_16 0x00010000U /*!< Pin 16 inside pin list of component */ +#define LDD_BITSIO_PIN_17 0x00020000U /*!< Pin 17 inside pin list of component */ +#define LDD_BITSIO_PIN_18 0x00040000U /*!< Pin 18 inside pin list of component */ +#define LDD_BITSIO_PIN_19 0x00080000U /*!< Pin 19 inside pin list of component */ +#define LDD_BITSIO_PIN_20 0x00100000U /*!< Pin 20 inside pin list of component */ +#define LDD_BITSIO_PIN_21 0x00200000U /*!< Pin 21 inside pin list of component */ +#define LDD_BITSIO_PIN_22 0x00400000U /*!< Pin 22 inside pin list of component */ +#define LDD_BITSIO_PIN_23 0x00800000U /*!< Pin 23 inside pin list of component */ +#define LDD_BITSIO_PIN_24 0x01000000U /*!< Pin 24 inside pin list of component */ +#define LDD_BITSIO_PIN_25 0x02000000U /*!< Pin 25 inside pin list of component */ +#define LDD_BITSIO_PIN_26 0x04000000U /*!< Pin 26 inside pin list of component */ +#define LDD_BITSIO_PIN_27 0x08000000U /*!< Pin 27 inside pin list of component */ +#define LDD_BITSIO_PIN_28 0x10000000U /*!< Pin 28 inside pin list of component */ +#define LDD_BITSIO_PIN_29 0x20000000U /*!< Pin 29 inside pin list of component */ +#define LDD_BITSIO_PIN_30 0x40000000U /*!< Pin 30 inside pin list of component */ +#define LDD_BITSIO_PIN_31 0x80000000U /*!< Pin 31 inside pin list of component */ + +/* +** =================================================================== +** Ethernet device types and constants +** =================================================================== +*/ + +#define LDD_ETH_MDC_PIN 0x01u /*!< MDC pin mask */ +#define LDD_ETH_MDIO_PIN 0x02u /*!< MDIO pin mask */ +#define LDD_ETH_COL_PIN 0x04u /*!< COL pin mask */ +#define LDD_ETH_CRS_PIN 0x08u /*!< CRS pin mask */ +#define LDD_ETH_TXCLK_PIN 0x10u /*!< TXCLK pin mask */ +#define LDD_ETH_TXD0_PIN 0x20u /*!< TXD0 pin mask */ +#define LDD_ETH_TXD1_PIN 0x40u /*!< TXD1 pin mask */ +#define LDD_ETH_TXD2_PIN 0x80u /*!< TXD2 pin mask */ +#define LDD_ETH_TXD3_PIN 0x0100u /*!< TXD3 pin mask */ +#define LDD_ETH_TXEN_PIN 0x0200u /*!< TXEN pin mask */ +#define LDD_ETH_TXER_PIN 0x0400u /*!< TXER pin mask */ +#define LDD_ETH_RXCLK_PIN 0x0800u /*!< RXCLK pin mask */ +#define LDD_ETH_RXDV_PIN 0x1000u /*!< RXDV pin mask */ +#define LDD_ETH_RXD0_PIN 0x2000u /*!< RXD0 pin mask */ +#define LDD_ETH_RXD1_PIN 0x4000u /*!< RXD1 pin mask */ +#define LDD_ETH_RXD2_PIN 0x8000u /*!< RXD2 pin mask */ +#define LDD_ETH_RXD3_PIN 0x00010000u /*!< RXD3 pin mask */ +#define LDD_ETH_RXER_PIN 0x00020000u /*!< RXER pin mask */ + +#define LDD_ETH_ON_FRAME_TRANSMITTED 0x01u /*!< OnFrameTransmitted event mask */ +#define LDD_ETH_ON_FRAME_TRANSMITTED_TIMESTAMPED 0x02u /*!< OnFrameTransmittedTimestamped event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED 0x04u /*!< OnFrameReceived event mask */ +#define LDD_ETH_ON_FRAME_RECEIVED_TIMESTAMPED 0x08u /*!< OnFrameReceivedTimestamped event mask */ +#define LDD_ETH_ON_MII_FINISHED 0x10u /*!< OnMIIFinished event mask */ +#define LDD_ETH_ON_FATAL_ERROR 0x20u /*!< OnFatalError event mask */ +#define LDD_ETH_ON_WAKE_UP 0x40u /*!< OnWakeUp event mask */ + +typedef uint8_t LDD_ETH_TMACAddress[6]; /*!< Ethernet MAC address */ + +/*! Ethernet duplex mode */ +typedef enum { + LDD_ETH_FULL_DUPLEX, /*!< Full duplex mode */ + LDD_ETH_HALF_DUPLEX /*!< Half duplex mode */ +} LDD_ETH_TDuplexMode; + +/*! Ethernet address filter mode options */ +typedef enum { + LDD_ETH_PROMISC, /*!< Promiscuous mode */ + LDD_ETH_REJECT_BC, /*!< Reject broadcast frames */ + LDD_ETH_ACCEPT_BC /*!< Accept broadcast frames */ +} LDD_ETH_TFilterMode; + +/*! Ethernet sleep mode options */ +typedef enum { + LDD_ETH_ENABLED, /*!< Sleep mode enabled */ + LDD_ETH_ENABLED_WITH_WAKEUP, /*!< Sleep mode enabled, waiting for wake-up */ + LDD_ETH_DISABLED /*!< Sleep mode disabled */ +} LDD_ETH_TSleepMode; + +/*! Ethernet frame buffer (fragment) descriptor */ +typedef struct { + uint8_t *DataPtr; /*!< Pointer to buffer data */ + uint16_t Size; /*!< Buffer data size */ +} LDD_ETH_TBufferDesc; + +typedef LDD_ETH_TBufferDesc* LDD_ETH_TBufferDescPtr; /*!< Frame buffer descriptor pointer type */ + +/*! Ethernet communication statistics */ +typedef struct { + uint32_t TxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t TxRMONOctets; /*!< Octet count for frames transmitted without error */ + uint32_t TxRMONPackets; /*!< Transmitted packet count */ + uint32_t TxRMONBroadcastPackets; /*!< Transmitted broadcast packets */ + uint32_t TxRMONMulticastPackets; /*!< Transmitted multicast packets */ + uint32_t TxRMONCRCAlignErrors; /*!< Transmitted packets with CRC or alignment error */ + uint32_t TxRMONUndersizePackets; /*!< Transmitted packets smaller than 64 bytes with good CRC */ + uint32_t TxRMONOversizePackets; /*!< Transmitted packets greater than max. frame length with good CRC */ + uint32_t TxRMONFragments; /*!< Transmitted packets smaller than 64 bytes with bad CRC */ + uint32_t TxRMONJabbers; /*!< Transmitted packets greater than max. frame length with bad CRC */ + uint32_t TxRMONCollisions; /*!< Transmit collision count */ + uint32_t TxRMONPackets64Octets; /*!< Transmitted 64 byte packets */ + uint32_t TxRMONPackets65To127Octets; /*!< Transmitted 65 to 127 byte packets */ + uint32_t TxRMONPackets128To255Octets; /*!< Transmitted 128 to 255 byte packets */ + uint32_t TxRMONPackets256To511Octets; /*!< Transmitted 256 to 511 byte packets */ + uint32_t TxRMONPackets512To1023Octets; /*!< Transmitted 512 to 1023 byte packets */ + uint32_t TxRMONPackets1024To2047Octets; /*!< Transmitted 1024 to 2047 byte packets */ + uint32_t TxRMONPacketsGreaterThan2048Octets; /*!< Transmitted packets greater than 2048 byte */ + uint32_t TxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t TxIEEEFrameOK; /*!< Frames transmitted OK */ + uint32_t TxIEEESingleCollision; /*!< Frames transmitted with single collision */ + uint32_t TxIEEEMultipleCollisions; /*!< Frames transmitted with multiple collisions */ + uint32_t TxIEEEDeferralDelay; /*!< Frames transmitted after deferral delay */ + uint32_t TxIEEELateCollision; /*!< Frames transmitted with late collision */ + uint32_t TxIEEEExcessiveCollision; /*!< Frames transmitted with excessive collisions */ + uint32_t TxIEEEFIFOUnderrun; /*!< Frames transmitted with transmit FIFO underrun */ + uint32_t TxIEEECarrierSenseError; /*!< Frames transmitted with carrier sense error */ + uint32_t TxIEEESQEError; /*!< Frames transmitted with SQE error */ + uint32_t TxIEEEPauseFrame; /*!< Flow control pause frames transmitted */ + uint32_t TxIEEEOctetsOK; /*!< Octet count for frames transmitted without error */ + uint32_t RxRMONDropEvents; /*!< Count of frames not counted correctly */ + uint32_t RxRMONOctets; /*!< Octet count for frames recieved without error */ + uint32_t RxRMONPackets; /*!< Received packet count */ + uint32_t RxRMONBroadcastPackets; /*!< Received broadcast packets */ + uint32_t RxRMONMulticastPackets; /*!< Received multicast packets */ + uint32_t RxRMONCRCAlignErrors; /*!< Received packets with CRC or alignment error */ + uint32_t RxRMONUndersizePackets; /*!< Received packets smaller than 64 bytes with good CRC */ + uint32_t RxRMONOversizePackets; /*!< Received packets greater than max. frame length with good CRC */ + uint32_t RxRMONFragments; /*!< Received packets smaller than 64 bytes with bad CRC */ + uint32_t RxRMONJabbers; /*!< Received packets greater than max. frame length with bad CRC */ + uint32_t RxRMONPackets64Octets; /*!< Received 64 byte packets */ + uint32_t RxRMONPackets65To127Octets; /*!< Received 65 to 127 byte packets */ + uint32_t RxRMONPackets128To255Octets; /*!< Received 128 to 255 byte packets */ + uint32_t RxRMONPackets256To511Octets; /*!< Received 256 to 511 byte packets */ + uint32_t RxRMONPackets512To1023Octets; /*!< Received 512 to 1023 byte packets */ + uint32_t RxRMONPackets1024To2047Octets; /*!< Received 1024 to 2047 byte packets */ + uint32_t RxRMONPacketsGreaterThan2048Octets; /*!< Received packets greater than 2048 byte */ + uint32_t RxIEEEDrop; /*!< Count of frames not counted correctly */ + uint32_t RxIEEEFrameOK; /*!< Frames received OK */ + uint32_t RxIEEECRCError; /*!< Frames received with CRC error */ + uint32_t RxIEEEAlignmentError; /*!< Frames received with alignment error */ + uint32_t RxIEEEFIFOOverflow; /*!< Receive FIFO overflow count */ + uint32_t RxIEEEPauseFrame; /*!< Flow control pause frames received */ + uint32_t RxIEEEOctetsOK; /*!< Octet count for frames received without error */ +} LDD_ETH_TStats; + +/* +** =================================================================== +** FlexCAN device types and constants +** =================================================================== +*/ + +typedef uint8_t LDD_CAN_TMBIndex; /*!< CAN message buffer index */ +typedef uint32_t LDD_CAN_TAccMask; /*!< Type specifying the acceptance mask variable. */ +typedef uint32_t LDD_CAN_TMessageID; /*!< Type specifying the ID mask variable. */ +typedef uint8_t LDD_CAN_TErrorCounter; /*!< Type specifying the error counter variable. */ +typedef uint32_t LDD_CAN_TErrorMask; /*!< Type specifying the error mask variable. */ +typedef uint16_t LDD_CAN_TBufferMask; /*!< Type specifying the message buffer mask variable. */ +#define LDD_CAN_RX_PIN 0x01U /*!< Rx pin mask */ +#define LDD_CAN_TX_PIN 0x02U /*!< Tx pin mask */ + +#define LDD_CAN_ON_FULL_RXBUFFER 0x01U /*!< OnFullRxBuffer event mask */ +#define LDD_CAN_ON_FREE_TXBUFFER 0x02U /*!< OnFreeTxBuffer event mask */ +#define LDD_CAN_ON_BUSOFF 0x04U /*!< OnBusOff event mask */ +#define LDD_CAN_ON_TXWARNING 0x08U /*!< OnTransmitterWarning event mask */ +#define LDD_CAN_ON_RXWARNING 0x10U /*!< OnReceiverWarning event mask */ +#define LDD_CAN_ON_ERROR 0x20U /*!< OnError event mask */ +#define LDD_CAN_ON_WAKEUP 0x40U /*!< OnWakeUp event mask */ + +#define LDD_CAN_BIT0_ERROR 0x4000UL /*!< Bit0 error detect error mask */ +#define LDD_CAN_BIT1_ERROR 0x8000UL /*!< Bit1 error detect error mask */ +#define LDD_CAN_ACK_ERROR 0x2000UL /*!< Acknowledge error detect error mask */ +#define LDD_CAN_CRC_ERROR 0x1000UL /*!< Cyclic redundancy check error detect error mask */ +#define LDD_CAN_FORM_ERROR 0x0800UL /*!< Message form error detect error mask */ +#define LDD_CAN_STUFFING_ERROR 0x0400UL /*!< Bit stuff error detect error mask */ + +#define LDD_CAN_MESSAGE_ID_EXT 0x80000000UL /*!< Value specifying extended Mask, ID */ + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_MB_RX_NOT_ACTIVE = 0x00U, + LDD_CAN_MB_RX_FULL = 0x02U, + LDD_CAN_MB_RX_EMPTY = 0x04U, + LDD_CAN_MB_RX_OVERRUN = 0x06U, + LDD_CAN_MB_RX_BUSY = 0x01U, + LDD_CAN_MB_RX_RANSWER = 0x0AU +} LDD_CAN_TRxBufferState; + +/*! Type specifying the CAN frame type. */ +typedef enum { + LDD_CAN_DATA_FRAME, /*!< Data frame type received or transmitted */ + LDD_CAN_REMOTE_FRAME, /*!< Remote frame type */ + LDD_CAN_RESPONSE_FRAME /*!< Response frame type - Tx buffer send data after receiving remote frame with the same ID */ +} LDD_CAN_TFrameType; + +/*! Type specifying the CAN communication statistics. */ +typedef struct { + uint32_t TxFrames; /*!< Transmitted frame counter */ + uint32_t TxWarnings; /*!< Transmission warning counter */ + uint32_t RxFrames; /*!< Received frame counter */ + uint32_t RxWarnings; /*!< Reception warning counter */ + uint32_t BusOffs; /*!< Bus off counter */ + uint32_t Wakeups; /*!< Wakeup counter */ + uint32_t Bit0Errors; /*!< Bit0 error counter */ + uint32_t Bit1Errors; /*!< Bit1 error counter */ + uint32_t AckErrors; /*!< ACK error counter */ + uint32_t CrcErrors; /*!< CRC error counter */ + uint32_t FormErrors; /*!< Message form error counter */ + uint32_t BitStuffErrors; /*!< Bit stuff error counter */ + uint32_t Errors; /*!< Error counter */ +} LDD_CAN_TStats; + +/*! Type specifying the CAN frame features. */ +typedef struct { + LDD_CAN_TMessageID MessageID; /*!< Message ID */ + LDD_CAN_TFrameType FrameType; /*!< Type of the frame DATA/REMOTE */ + uint8_t *Data; /*!< Message data buffer */ + uint8_t Length; /*!< Message length */ + uint16_t TimeStamp; /*!< Message time stamp */ + uint8_t LocPriority; /*!< Local Priority Tx Buffers */ +} LDD_CAN_TFrame; + +/* +** =================================================================== +** USB device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_USB_ON_DEVICE_RESET 0x00000001u /*!< OnDeviceReset event mask */ +#define LDD_USB_ON_DEVICE_SPEED_DETECT 0x00000002u /*!< OnDeviceSpeedDetect event mask */ +#define LDD_USB_ON_DEVICE_SUSPEND 0x00000004u /*!< OnDeviceSuspend event mask */ +#define LDD_USB_ON_DEVICE_RESUME 0x00000008u /*!< OnDeviceResume event mask */ +#define LDD_USB_ON_DEVICE_SETUP_PACKET 0x00000010u /*!< OnDeviceSetupPacket event mask */ +#define LDD_USB_ON_DEVICE_SOF 0x00000020u /*!< OnDeviceSof event mask */ +#define LDD_USB_ON_DEVICE_1MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_1_MS_TIMER 0x00000040u /*!< OnDevice1msTimer event mask */ +#define LDD_USB_ON_DEVICE_ERROR 0x00000080u /*!< OnDeviceError event mask */ +#define LDD_USB_ON_HOST_DEVICE_DEATTACH 0x00000100u /*!< OnHostDeviceAttach event mask */ +#define LDD_USB_ON_HOST_RESET_RECOVERY 0x00000200u /*!< OnHostResetRecovery event mask */ +#define LDD_USB_ON_HOST_RESUME_RECOVERY 0x00000400u /*!< OnHostResumeRecovery event mask */ +#define LDD_USB_ON_HOST_1MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_1_MS_TIMER 0x00000800u /*!< 1 ms timer event mask */ +#define LDD_USB_ON_HOST_ERROR 0x00001000u /*!< OnHostError event mask */ +#define LDD_USB_ON_OTG_DEVICE 0x00002000u /*!< OnOtgDevice event mask */ +#define LDD_USB_ON_OTG_HOST 0x00004000u /*!< OnOtgHost event mask */ +#define LDD_USB_ON_OTG_STATE_CHANGE 0x00008000u /*!< OnOtgStageChange event mask */ +#define LDD_USB_ON_SIGNAL_CHANGE 0x00010000u /*!< OnSignalChange event mask */ + +/* Data pins' masks */ +#define LDD_USB_DP_PIN 0x00000001u /*!< Data+ pin mask */ +#define LDD_USB_DM_PIN 0x00000002u /*!< Data- pin mask */ + +/* Pullup/pulldown pin masks */ +#define LDD_USB_DP_PU_PIN 0x00000004u /*!< Data+ pull-up pin mask */ +#define LDD_USB_DM_PU_PIN 0x00000008u /*!< Data- pull-up pin mask */ +#define LDD_USB_DP_PD_PIN 0x00000010u /*!< Data+ pull-down pin mask */ +#define LDD_USB_DM_PD_PIN 0x00000020u /*!< Data- pull-down pin mask */ + +/* VBUS pins' mask */ +#define LDD_USB_DEVICE_VBUS_DETECT_PIN 0x00000040u /*!< VBUS detect pin mask */ +#define LDD_USB_HOST_VBUS_ENABLE_PIN 0x00000080u /*!< VBUS enable pin mask */ +#define LDD_USB_HOST_VBUS_OVERCURRENT_PIN 0x00000100u /*!< VBUS overcurrent pin mask */ + +/* OTG pins' masks */ +#define LDD_USB_OTG_ID_PIN 0x00000200u /*!< ID pin mask */ +#define LDD_USB_OTG_VBUS_VALID_PIN 0x00000400u /*!< VBUS valid pin mask */ +#define LDD_USB_OTG_SESSION_VALID_PIN 0x00000800u /*!< SESSION valid pin mask */ +#define LDD_USB_OTG_B_SESSION_END_PIN 0x00004000u /*!< B SESSION end pin mask */ +#define LDD_USB_OTG_VBUS_ENABLE_PIN 0x00008000u /*!< VBUS drive pin mask */ +#define LDD_USB_OTG_VBUS_CHARGE_PIN 0x00010000u /*!< VBUS charge pin mask */ +#define LDD_USB_OTG_VBUS_DISCHARGE_PIN 0x00020000u /*!< VBUS discharge pin mask */ + +/* ULPI pins' masks */ +#define LDD_USB_ULPI_CLK_PIN 0x00080000u /*!< ULPI_CLK pin mask */ +#define LDD_USB_ULPI_DIR_PIN 0x00100000u /*!< ULPI_DIR pin mask */ +#define LDD_USB_ULPI_NXT_PIN 0x00200000u /*!< ULPI_NXT pin mask */ +#define LDD_USB_ULPI_STP_PIN 0x00400000u /*!< ULPI_STOP pin mask */ +#define LDD_USB_ULPI_DATA_0_PIN 0x00800000u /*!< ULPI_DATA_0 pin mask */ +#define LDD_USB_ULPI_DATA_1_PIN 0x01000000u /*!< ULPI_DATA_1 pin mask */ +#define LDD_USB_ULPI_DATA_2_PIN 0x02000000u /*!< ULPI_DATA_2 pin mask */ +#define LDD_USB_ULPI_DATA_3_PIN 0x04000000u /*!< ULPI_DATA_3 pin mask */ +#define LDD_USB_ULPI_DATA_4_PIN 0x08000000u /*!< ULPI_DATA_4 pin mask */ +#define LDD_USB_ULPI_DATA_5_PIN 0x10000000u /*!< ULPI_DATA_5 pin mask */ +#define LDD_USB_ULPI_DATA_6_PIN 0x20000000u /*!< ULPI_DATA_6 pin mask */ +#define LDD_USB_ULPI_DATA_7_PIN 0x40000000u /*!< ULPI_DATA_7 pin mask */ + +/* Alternate clock pin*/ +#define LDD_USB_CLKIN_PIN 0x80000000u /*!< Alternate clock pin mask */ +#define LDD_USB_ALT_CLK_PIN 0x80000000u /*!< Alternate clock pin mask */ + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Cmd/CmdStatusPtr param. values */ +#define LDD_USB_CMD_GET_EP_STATUS 0x00u /*!< Get endpoint status command ID */ +#define LDD_USB_CMD_SET_EP_HALT_FATURE 0x01u /*!< Set endpoint HALT feature command ID */ +#define LDD_USB_CMD_CLR_EP_HALT_FATURE 0x02u /*!< Clear endpoint HALT feature command ID */ + +#define LDD_USB_CMD_EP_STATUS_HALT_MASK 0x01u /*!< Endpoint halt status mask */ + + +/* DeviceSetUsbStatus()/DeviceGetUsbStatus methods Recipient param. values */ +/* (see USB 2.0, chapter 9.3.4 wIndex description)*/ +#define LDD_USB_ID_EP0_OUT 0x00u /*!< EP0 OUT component ID */ +#define LDD_USB_ID_EP0_IN 0x80u /*!< EP0 IN component ID */ +#define LDD_USB_ID_EP1_OUT 0x01u /*!< EP1 OUT component ID */ +#define LDD_USB_ID_EP1_IN 0x81u /*!< EP1 IN component ID */ +#define LDD_USB_ID_EP2_OUT 0x02u /*!< EP2 OUT component ID */ +#define LDD_USB_ID_EP2_IN 0x82u /*!< EP2 IN component ID */ +#define LDD_USB_ID_EP3_OUT 0x03u /*!< EP3 OUT component ID */ +#define LDD_USB_ID_EP3_IN 0x83u /*!< EP3 IN component ID */ +#define LDD_USB_ID_EP4_OUT 0x04u /*!< EP4 OUT component ID */ +#define LDD_USB_ID_EP4_IN 0x84u /*!< EP4 IN component ID */ +#define LDD_USB_ID_EP5_OUT 0x05u /*!< EP5 OUT component ID */ +#define LDD_USB_ID_EP5_IN 0x85u /*!< EP5 IN component ID */ +#define LDD_USB_ID_EP6_OUT 0x06u /*!< EP6 OUT component ID */ +#define LDD_USB_ID_EP6_IN 0x86u /*!< EP6 IN component ID */ +#define LDD_USB_ID_EP7_OUT 0x07u /*!< EP7 OUT component ID */ +#define LDD_USB_ID_EP7_IN 0x87u /*!< EP7 IN component ID */ +#define LDD_USB_ID_EP8_OUT 0x08u /*!< EP8 OUT component ID */ +#define LDD_USB_ID_EP8_IN 0x88u /*!< EP8 IN component ID */ +#define LDD_USB_ID_EP9_OUT 0x09u /*!< EP9 OUT component ID */ +#define LDD_USB_ID_EP9_IN 0x89u /*!< EP9 IN component ID */ +#define LDD_USB_ID_EP10_OUT 0x0Au /*!< EP10 OUT component ID */ +#define LDD_USB_ID_EP10_IN 0x8Au /*!< EP10 IN component ID */ +#define LDD_USB_ID_EP11_OUT 0x0Bu /*!< EP11 OUT component ID */ +#define LDD_USB_ID_EP11_IN 0x8Bu /*!< EP11 IN component ID */ +#define LDD_USB_ID_EP12_OUT 0x0Cu /*!< EP12 OUT component ID */ +#define LDD_USB_ID_EP12_IN 0x8Cu /*!< EP12 IN component ID */ +#define LDD_USB_ID_EP13_OUT 0x0Du /*!< EP13 OUT component ID */ +#define LDD_USB_ID_EP13_IN 0x8Du /*!< EP13 IN component ID */ +#define LDD_USB_ID_EP14_OUT 0x0Eu /*!< EP14 OUT component ID */ +#define LDD_USB_ID_EP14_IN 0x8Eu /*!< EP14 IN component ID */ +#define LDD_USB_ID_EP15_OUT 0x0Fu /*!< EP15 OUT component ID */ +#define LDD_USB_ID_EP15_IN 0x8Fu /*!< EP15 IN component ID */ +#define LDD_USB_ID_EP_MASK 0x8Fu /*!< EP15 IN component ID */ + +/* Token PID */ +#define LDD_USB_PID_OUT 0x01u /*!< OUT */ +#define LDD_USB_PID_IN 0x09u /*!< IN */ +#define LDD_USB_PID_SOF 0x05u /*!< SOF */ +#define LDD_USB_PID_SETUP 0x0Du /*!< SETUP */ +/* Data PID */ +#define LDD_USB_PID_DATA0 0x03u /*!< DATA0 */ +#define LDD_USB_PID_DATA1 0x0Bu /*!< DATA1 */ +#define LDD_USB_PID_DATA2 0x07u /*!< DATA2 */ +#define LDD_USB_PID_MDATA 0x0Fu /*!< MDATA */ +/* Handshake PID */ +#define LDD_USB_PID_ACK 0x02u /*!< ACK */ +#define LDD_USB_PID_NACK 0x0Au /*!< NACK */ +#define LDD_USB_PID_STALL 0x0Eu /*!< STALL */ +#define LDD_USB_PID_NYET 0x06u /*!< NYET */ +/* Special PID */ +#define LDD_USB_PID_PRE 0x0Cu /*!< PRE */ +#define LDD_USB_PID_ERR 0x0Cu /*!< ERR */ +#define LDD_USB_PID_SPLIT 0x08u /*!< SPLIT */ +#define LDD_USB_PID_PING 0x04u /*!< PING */ + +/* Data direction */ +#define LDD_USB_DIR_OUT 0x00u /*!< Recipient is Device */ +#define LDD_USB_DIR_IN 0x80u /*!< Recipient is Host */ +#define LDD_USB_DIR_MASK 0x80u /*!< Bit mask for data transfer direction */ + +/* Flags used in the TD.Head.Flags variable */ + +/* The following flag can be used to force zero-length termination(ZLT) of the transfer. + Note: ZLT can be set for all transfer during the initialization of the endpoint. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_ZLT 0x01u + +/* If the TRANSFER_FLAG_EXT_PARAM is defined all variables of the TD are used + and TD must NOT be freed until transfer is done or is cancelled + (TransferState != LDD_USB_TRANSFER_PENDING) + If not defined only the Head member of TD is used and TD can be freed after + Send/Recv() method returns. +*/ +#define LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM 0x02u + + +#define ERR_COMPONET_SPECIFIC 0x100u + +/* Device mode USB specific error codes */ +#define ERR_USB_DEVICE_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Device mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_DEVICE_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Device mode is disabled by the OTG driver */ +#define ERR_USB_DEVICE_VBUS_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< No VBUS is detected */ +#define ERR_USB_DEVICE_VBUS_ON (ERR_COMPONET_SPECIFIC + 0x03u) /*!< VBUS is detected */ +#define ERR_USB_DEVICE_ENABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is enabled */ +#define ERR_USB_DEVICE_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Device is suspended */ +#define ERR_USB_DEVICE_SUSPENDED_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Device is suspended and ready to generate resume signaling */ +#define ERR_USB_DEVICE_RESUME_PENDING (ERR_COMPONET_SPECIFIC + 0x07u) /*!< Device generates resume signaling */ + +/* Host mode USB specific error codes */ +#define ERR_USB_HOST_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< Host mode is disabled (by the user or by the clock configuration) */ +#define ERR_USB_HOST_DISABLED_BY_OTG (ERR_COMPONET_SPECIFIC + 0x01u) /*!< Host mode is disabled by the OTG driver */ +#define ERR_USB_HOST_PORT_POWERED_OFF (ERR_COMPONET_SPECIFIC + 0x02u) /*!< Port is power off */ +#define ERR_USB_HOST_PORT_DISCONNECTED (ERR_COMPONET_SPECIFIC + 0x03u) /*!< Port is power on */ +#define ERR_USB_HOST_PORT_DISABLED (ERR_COMPONET_SPECIFIC + 0x04u) /*!< Device is connected to the port */ +#define ERR_USB_HOST_PORT_RESETING (ERR_COMPONET_SPECIFIC + 0x05u) /*!< Port generates reset signaling */ +#define ERR_USB_HOST_PORT_RESET_RECOVERING (ERR_COMPONET_SPECIFIC + 0x06u) /*!< Port waits 10ms for reset recovery */ +#define ERR_USB_HOST_PORT_ENABLED (ERR_COMPONET_SPECIFIC + 0x07u) /*!< PortDevice is connected, reset and ready to use */ +#define ERR_USB_HOST_PORT_SUSPENDED (ERR_COMPONET_SPECIFIC + 0x08u) /*!< Port is suspended */ +#define ERR_USB_HOST_PORT_RESUME_READY (ERR_COMPONET_SPECIFIC + 0x09u) /*!< Port can generate resume signaling */ +#define ERR_USB_HOST_PORT_RESUMING (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< Port generates resume signaling */ +#define ERR_USB_HOST_PORT_RESUME_RECOVERING (ERR_COMPONET_SPECIFIC + 0x0Bu) /*!< Port generates resume signaling */ + +/* OTG mode USB specific error codes */ +#define ERR_USB_OTG_DISABLED (ERR_COMPONET_SPECIFIC + 0x00u) /*!< OTG device is DISABLED state */ +#define ERR_USB_OTG_ENABLED_PENDING (ERR_COMPONET_SPECIFIC + 0x01u) /*!< OTG device is in ENABLED_PENDING state */ +#define ERR_USB_OTG_A_IDLE (ERR_COMPONET_SPECIFIC + 0x02u) /*!< OTG device is in A_IDLE state */ +#define ERR_USB_OTG_A_WAIT_VRISE (ERR_COMPONET_SPECIFIC + 0x03u) /*!< OTG device is in WAIT_VRISE state */ +#define ERR_USB_OTG_A_WAIT_VFALL (ERR_COMPONET_SPECIFIC + 0x05u) /*!< OTG device is in A_WAIT_VFALL state */ +#define ERR_USB_OTG_A_WAIT_BCON (ERR_COMPONET_SPECIFIC + 0x07u) /*!< OTG device is in A_WAIT_BCON state */ +#define ERR_USB_OTG_A_VBUS_ERROR (ERR_COMPONET_SPECIFIC + 0x09u) /*!< OTG device is in A_VBUS_ERROR state */ +#define ERR_USB_OTG_A_SUSPEND (ERR_COMPONET_SPECIFIC + 0x0Au) /*!< OTG device is in A_SUSPEND state */ + +#define ERR_USB_OTG_B_IDLE (ERR_COMPONET_SPECIFIC + 0x0Cu) /*!< OTG device is in B_IDLE state */ +#define ERR_USB_OTG_B_SRP_INIT (ERR_COMPONET_SPECIFIC + 0x0Eu) /*!< OTG device is in B_SRP_INIT state */ +#define ERR_USB_OTG_B_WAIT_ACON (ERR_COMPONET_SPECIFIC + 0x0Fu) /*!< OTG device is in B_WAIT_ACON state */ + +#define ERR_USB_OTG_A_HOST (ERR_COMPONET_SPECIFIC + 0x10u) /*!< OTG device is in A_HOST state */ +#define ERR_USB_OTG_A_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x11u) /*!< OTG device is in A_PERIPHERAL state */ +#define ERR_USB_OTG_B_HOST (ERR_COMPONET_SPECIFIC + 0x12u) /*!< OTG device is in B_HOST state */ +#define ERR_USB_OTG_B_PERIPHERAL (ERR_COMPONET_SPECIFIC + 0x13u) /*!< OTG device is in B_PERIPHERAL state */ + +/*! Device speed symbolic names */ +typedef enum { + LDD_USB_LOW_SPEED = 0x00u, /*!< Low-speed - 6 Mb/s mode */ + LDD_USB_FULL_SPEED = 0x01u, /*!< Full-speed - 12 Mb/s mode */ + LDD_USB_HIGH_SPEED = 0x02u, /*!< High-speed - 480 Mb/s mode */ + LDD_USB_SPEED_UNKNOWN = 0xFFu /*!< Unkown speed mode */ +} LDD_USB_TBusSpeed; + +/*! Transfer type symbolic names */ +typedef enum { + LDD_USB_CONTROL = 0x00u, /*!< Conrol transfer type */ + LDD_USB_ISOCHRONOUS = 0x01u, /*!< Isochronous transfer type */ + LDD_USB_BULK = 0x02u, /*!< Bulk transfer type */ + LDD_USB_INTERRUPT = 0x03u /*!< Interrupt transfer type */ +} LDD_USB_TTransferType; + +/*! Transfer state symbolic names */ +typedef enum { + LDD_USB_TRANSFER_NONE = 0x00u, /*!< Default valeu for new TD */ + LDD_USB_TRANSFER_DONE = 0x01u, /*!< Transfer done */ + LDD_USB_TRANSFER_ERROR_CANCELLED = 0x02u, /*!< Transfer cancelled by the user */ + LDD_USB_TRANSFER_ERROR_STALLED = 0x03u, /*!< Transfer stalled */ + LDD_USB_TRANSFER_ERROR_BUS_TIMEOUT = 0x04u, /*!< Bus timeute detected */ + LDD_USB_TRANSFER_ERROR_DATA = 0x05u, /*!< Data error deteceted */ + LDD_USB_TRANSFER_ERROR_PID = 0x06u, /*!< PID error deteceted */ + LDD_USB_TRANSFER_ERROR_EOF = 0x07u, /*!< EOF error deteceted */ + LDD_USB_TRANSFER_ERROR_CRC16 = 0x08u, /*!< CRC16 error deteceted */ + LDD_USB_TRANSFER_ERROR_DFN8 = 0x09u, /*!< DFN8 error deteceted */ + LDD_USB_TRANSFER_ERROR_DMA = 0x0Au, /*!< DMA error deteceted */ + LDD_USB_TRANSFER_ERROR_BTS = 0x0Bu, /*!< BTS error deteceted */ + LDD_USB_TRANSFER_ERROR = 0x0Fu, /*!< Transfer error deteceted */ + LDD_USB_TRANSFER_QUEUED = 0x10u, /*!< Transfer queued */ + LDD_USB_TRANSFER_PENDING = 0x30u /*!< Transfer in proggress */ +} LDD_USB_TTransferState; + +/*! Setup data packet structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TSDP_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request code */ + uint16_t wValue; /*!< Word-sized field that varies according to request */ + uint16_t wIndex; /*!< Word-sized field that varies according to request, typically used to pass an index or offset */ + uint16_t wLength; /*!< Number of bytes to transfer if there is a data stage */ +} LDD_USB_TSDP; + +/*! Endpoint descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TEpDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint8_t bEndpointAddress; /*!< Endpoint address */ + uint8_t bmAttributes; /*!< Endpoint attributes */ + uint16_t wMaxPacketSize; /*!< Maximum packet size the endpoint is capable of sending or receiving */ + uint8_t bInterval; /*!< Interval for polling endpoint for data transfers */ +} LDD_USB_TEpDescriptor; + +/*! Standard device descriptor structure, uint16_t items must be in little-endian format */ +typedef struct LDD_USB_TDevDescriptor_Struct { + uint8_t bLength; /*!< Size of this descriptor in bytes */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t bcdUSB; /*!< USB specification release number in binary-coded Decimal */ + uint8_t bDeviceClass; /*!< Class code (assigned by the USB-IF) */ + uint8_t bDeviceSubClass; /*!< Subclass code (assigned by the USB-IF) */ + uint8_t bDeviceProtocol; /*!< Protocol code (assigned by the USB-IF) */ + uint8_t bMaxPacketSize0; /*!< Maximum packet size for endpoint zero */ + uint16_t idVendor; /*!< Vendor ID (assigned by the USB-IF) */ + uint16_t idProduct; /*!< Product ID (assigned by the manufacturer) */ + uint16_t bcdDevice; /*!< Device release number in binary-coded decimal */ + uint8_t iManufacturer; /*!< Index of string descriptor describing manufacturer */ + uint8_t iProduct; /*!< Index of string descriptor describing product */ + uint8_t iSerialNumber; /*!< Index of string descriptor describing the device’s serial number */ + uint8_t bNumConfigurations; /*!< Number of possible configurations */ +} LDD_USB_TDevDescriptor; + + +/*! Device transfer descriptor structure forward declaration */ +struct LDD_USB_Device_TTD_Struct; + +/*! Device transfer done callback prototype */ +typedef void (LDD_USB_Device_TTransferDoneCalback)(LDD_TDeviceData *DevDataPtr, struct LDD_USB_Device_TTD_Struct *TrParamPtr); + +/*! Device transfer descriptor structure - head part */ +typedef struct LDD_USB_Device_TTD_Head_Struct { + uint8_t EpNum; /*!< Endpoint number */ + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags - see constants definition */ +} LDD_USB_Device_TTD_Head; + +/*! Device transfer descriptor structure */ +typedef struct LDD_USB_Device_TTD_Struct { + /* Requierd variables */ + LDD_USB_Device_TTD_Head Head; /*!< Td head data, not changed by the driver */ + /* Optional items - the following items are used */ + /* only if Head.Flags & LDD_USB_DEVICE_TRANSFER_FLAG_EXT_PARAM != 0 */ + LDD_USB_TTransferState TransferState; /*!< Transfer state. Set by the driver */ + uint16_t TransmittedDataSize; /*!< Transmitted data size. Set by the driver */ + LDD_USB_Device_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ +} LDD_USB_Device_TTD; + +/*! USB device states symbolic names */ +typedef enum { + LDD_USB_DEVICE_DISABLED = ERR_USB_DEVICE_DISABLED, /*!< Device mode is disabled (by the user or by the clock configuration) */ + LDD_USB_DEVICE_DISABLED_BY_OTG = ERR_USB_DEVICE_DISABLED_BY_OTG, /*!< Device mode is disabled by the OTG driver */ + LDD_USB_DEVICE_VBUS_OFF = ERR_USB_DEVICE_VBUS_OFF, /*!< No VBUS is detected */ + LDD_USB_DEVICE_VBUS_ON = ERR_USB_DEVICE_VBUS_ON, /*!< VBUS is detected */ + LDD_USB_DEVICE_ENABLED = ERR_USB_DEVICE_ENABLED, /*!< Device is enabled - reset by the host */ + LDD_USB_DEVICE_SUSPENDED = ERR_USB_DEVICE_SUSPENDED, /*!< Device is suspended - Bus is idle more then 3 ms */ + LDD_USB_DEVICE_SUSPENDED_RESUME_READY = ERR_USB_DEVICE_SUSPENDED_RESUME_READY, /*!< Device can generate resume signaling - Bus is idle more then 5 ms. */ + LDD_USB_DEVICE_RESUME_PENDING = ERR_USB_DEVICE_RESUME_PENDING /*!< Device generates resume signaling */ +} LDD_USB_Device_TState; + +/*! USB host mode states symbolic names */ +typedef enum { + LDD_USB_HOST_DISABLED = ERR_USB_HOST_DISABLED, /*!< Host mode is disabled (by the user or by the clock configuration) */ + LDD_USB_HOST_DISABLED_BY_OTG = ERR_USB_HOST_DISABLED_BY_OTG, /*!< Host mode is disabled by the OTG driver */ + LDD_USB_HOST_PORT_POWERED_OFF = ERR_USB_HOST_PORT_POWERED_OFF, /*!< Port is powered-off */ + LDD_USB_HOST_PORT_DISCONNECTED = ERR_USB_HOST_PORT_DISCONNECTED, /*!< No device is connected */ + LDD_USB_HOST_PORT_DISABLED = ERR_USB_HOST_PORT_DISABLED, /*!< Device is connected to the port */ + LDD_USB_HOST_PORT_RESETING = ERR_USB_HOST_PORT_RESETING, /*!< Port generates reset signaling */ + LDD_USB_HOST_PORT_RESET_RECOVERING = ERR_USB_HOST_PORT_RESET_RECOVERING, /*!< Port waits 10 ms for reset recovery */ + LDD_USB_HOST_PORT_ENABLED = ERR_USB_HOST_PORT_ENABLED, /*!< Device is connected, reset and ready to use */ + LDD_USB_HOST_PORT_SUSPENDED = ERR_USB_HOST_PORT_SUSPENDED, /*!< Port is suspended */ + LDD_USB_HOST_PORT_RESUME_READY = ERR_USB_HOST_PORT_RESUME_READY, /*!< Port is ready to generate resume signaling */ + LDD_USB_HOST_PORT_RESUMING = ERR_USB_HOST_PORT_RESUMING, /*!< Port generates resume signaling */ + LDD_USB_HOST_PORT_RESUME_RECOVERING = ERR_USB_HOST_PORT_RESUME_RECOVERING /*!< Port waits 10 ms for resume recovery */ +} LDD_USB_Host_TState; + +/*! USB otg mode states symbolic names */ +typedef enum { + LDD_USB_OTG_DISABLED = ERR_USB_OTG_DISABLED, /*!< OTG device is in DISABLED state */ + LDD_USB_OTG_ENABLED = ERR_USB_OTG_ENABLED_PENDING, /*!< OTG device is in ENABLED_PENDING state */ + LDD_USB_OTG_A_IDLE = ERR_USB_OTG_A_IDLE, /*!< OTG device is in A_IDLE state */ + LDD_USB_OTG_A_WAIT_VRISE = ERR_USB_OTG_A_WAIT_VRISE, /*!< OTG device is in A_WAIT_VRISE state */ + LDD_USB_OTG_A_WAIT_VFALL = ERR_USB_OTG_A_WAIT_VFALL, /*!< OTG device is in A_WAIT_VFALL state */ + LDD_USB_OTG_A_WAIT_BCON = ERR_USB_OTG_A_WAIT_BCON, /*!< OTG device is in A_WAIT_BCON state */ + LDD_USB_OTG_A_VBUS_ERROR = ERR_USB_OTG_A_VBUS_ERROR, /*!< OTG device is in A_VBUS_ERROR state */ + LDD_USB_OTG_A_SUSPEND = ERR_USB_OTG_A_SUSPEND, /*!< OTG device is in A_SUSPEND state */ + LDD_USB_OTG_B_IDLE = ERR_USB_OTG_B_IDLE, /*!< OTG device is in B_IDLE state */ + LDD_USB_OTG_B_SRP_INIT = ERR_USB_OTG_B_SRP_INIT, /*!< OTG device is in B_SRP_INIT state */ + LDD_USB_OTG_B_WAIT_ACON = ERR_USB_OTG_B_WAIT_ACON, /*!< OTG device is in B_WAIT_ACON state */ + LDD_USB_OTG_A_HOST = ERR_USB_OTG_A_HOST, /*!< OTG device is in A_HOST state */ + LDD_USB_OTG_A_PERIPHERAL = ERR_USB_OTG_A_PERIPHERAL, /*!< OTG device is in A_PERIPHERAL state */ + LDD_USB_OTG_B_HOST = ERR_USB_OTG_B_HOST, /*!< OTG device is in B_HOST state */ + LDD_USB_OTG_B_PERIPHERAL = ERR_USB_OTG_B_PERIPHERAL /*!< OTG device is in B_PERIPHERAL state */ +} LDD_USB_Otg_TState; + +/*! USB Otg commands symbolic names */ +typedef enum { + LDD_USB_OTG_CMD_SET_A_BUS_REQUEST, /*!< A-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_REQUEST, /*!< A-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_B_BUS_REQUEST, /*!< B-device application wants to use the bus */ + LDD_USB_OTG_CMD_CLR_B_BUS_REQUEST, /*!< B-device application doesn't want to use the bus */ + LDD_USB_OTG_CMD_SET_A_BUS_DROP, /*!< A-device application needs to power down the bus */ + LDD_USB_OTG_CMD_CLR_A_BUS_DROP, /*!< A-device application doesn't need to power down the bus */ + LDD_USB_OTG_CMD_SET_A_SUSPEND_REQUEST, /*!< A-device application wants to suspend the bus */ + LDD_USB_OTG_CMD_CLR_A_SUSPEND_REQUEST, /*!< A-device application doesn't want to suspend the bus */ + LDD_USB_OTG_CMD_SET_A_SET_B_HNP_EN_REQUEST, /*!< A-device sets HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_CLR_A_SET_B_HNP_EN_REQUEST, /*!< A-device clears HNP enabled feature on B-device */ + LDD_USB_OTG_CMD_SET_B_HNP_EN_REQUEST, /*!< Enable B-device HNP */ + LDD_USB_OTG_CMD_CLR_B_HNP_EN_REQUEST /*!< Disable B-device HNP */ +} LDD_USB_Otg_TCmd; + +/*! USB host port control commands symbolic names */ +typedef enum { + LDD_USB_HOST_PORT_CMD_POWER_ON, /*!< Power-on the bus */ + LDD_USB_HOST_PORT_CMD_POWER_OFF, /*!< Power-off the bus */ + LDD_USB_HOST_PORT_CMD_RESET, /*!< Perform the bus reset signaling and call event after the reset recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_RESUME, /*!< Perform the bus resume signaling and call event after the resume recovery interval elapse */ + LDD_USB_HOST_PORT_CMD_SUSPEND, /*!< Suspend the bus and transceiver */ + LDD_USB_HOST_PORT_CMD_DISABLE /*!< Disable the port */ +} LDD_USB_Host_TPortControlCmd; + +/*! USB host handle prototypes */ +typedef void LDD_USB_Host_TPipeHandle; /*!< Pipe handle prototype */ +typedef void LDD_USB_Host_TTransferHandle; /*!< Transfer handle prototype */ + +/*! USB host pipe descriptor structure */ +typedef struct LDD_USB_Host_TPipeDescr_Struct { + uint8_t DevAddress; /*!< Device address */ + LDD_USB_TBusSpeed DevSpeed; /*!< Device speed */ + uint8_t EpNumber; /*!< EP number */ + uint8_t EpDir; /*!< EP direction */ + LDD_USB_TTransferType TransferType; /*!< EP Transfer type */ + uint16_t MaxPacketSize; /*!< EP max. packet size */ + uint8_t TrPerUFrame; /*!< Transaction pre microframe */ + uint32_t Interval; /*!< Interval for polling endpoint for data transfers */ + uint32_t NAKCount; /*!< NAK count */ + uint8_t Flags; /*!< 1 = ZLT */ +} LDD_USB_Host_TPipeDescr; + +/*! USB host transfer done callback prototype */ +typedef void (LDD_USB_Host_TTransferDoneCalback)( + LDD_TDeviceData *DevDataPtr, /*!< User value passed as parameter of the Init() method */ + LDD_TData *BufferPtr, /*!< Buffer address */ + uint16_t BufferSize, /*!< Transferred data size */ + uint8_t *ParamPtr, /*!< User value passed in Send()/Recv() method */ + LDD_USB_TTransferState Status /*!< Transfer status */ +); + +/*! USB host transfer descriptor structure */ +typedef struct LDD_USB_Host_TTD_Struct { + LDD_TData *BufferPtr; /*!< Buffer address */ + uint16_t BufferSize; /*!< Buffer size */ + uint8_t Flags; /*!< Transfer flags */ + LDD_USB_Host_TTransferDoneCalback *CallbackFnPtr; /*!< Address of the callback function. Must be set by the caller */ + uint8_t *ParamPtr; /*!< User parameter. Not changed by the driver */ + LDD_USB_TSDP *SDPPrt; /*!< Setup data buffer pointer */ +} LDD_USB_Host_TTD; + +/*! Following USB constants and types are for test purpose only */ + +/* Request types */ +#define LDD_USB_REQ_TYPE_STANDARD 0x00u /*!< Standard request */ +#define LDD_USB_REQ_TYPE_CLASS 0x20u /*!< Class request */ +#define LDD_USB_REQ_TYPE_VENDOR 0x40u /*!< Vendor request */ +#define LDD_USB_REQ_TYPE_MASK 0x60u /*!< Bit mask for request type (bmRequestType) */ + +/* Request recepient */ +#define LDD_USB_REQ_RECP_DEVICE 0x00u /*!< Recipient = Device */ +#define LDD_USB_REQ_RECP_INTERFACE 0x01u /*!< Recipient = Interface */ +#define LDD_USB_REQ_RECP_ENDPOINT 0x02u /*!< Recipient = Endpoint */ +#define LDD_USB_REQ_RECP_OTHER 0x03u /*!< Recipient = Other */ +#define LDD_USB_REQ_RECP_MASK 0x03u /*!< Bit mask for recipient */ + +/* Standard request codes (bRequest) */ +#define LDD_USB_REQ_GET_STATUS 0x00u /*!< GET_STATUS request code */ +#define LDD_USB_REQ_CLEAR_FEATURE 0x01u /*!< CLEAR_FEATURE request code */ +#define LDD_USB_REQ_SET_FEATURE 0x03u /*!< SET_FEATURE request code */ +#define LDD_USB_REQ_GET_STATE 0x04u /*!< GET_STATE request code (for Hub Class only)*/ +#define LDD_USB_REQ_SET_ADDRESS 0x05u /*!< SET_ADDRESS request code */ +#define LDD_USB_REQ_GET_DESCRIPTOR 0x06u /*!< GET_DESCRIPTOR request code */ +#define LDD_USB_REQ_SET_DESCRIPTOR 0x07u /*!< SET_DESCRIPTOR request code, this request is not supported */ +#define LDD_USB_REQ_GET_CONFIGURATION 0x08u /*!< GET_CONFIGURATION request code */ +#define LDD_USB_REQ_SET_CONFIGURATION 0x09u /*!< SET_CONFIGURATION request code */ +#define LDD_USB_REQ_GET_INTERFACE 0x0Au /*!< GET_INTERFACE request code */ +#define LDD_USB_REQ_SET_INTERFACE 0x0Bu /*!< SET_INTERFACE request code */ +#define LDD_USB_REQ_SYNCH_FRAME 0x0Cu /*!< SYNCH_FRAME request code */ + +/* Standard request words for device (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_DEV_STATUS 0x0080u /*!< GET_DEVICE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_DEV_FEATURE 0x0100u /*!< CLEAR_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DEV_FEATURE 0x0300u /*!< SET_DEVICE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_ADDRESS 0x0500u /*!< SET_DEVICE_ADDRESS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_DESCRIPTOR 0x0680u /*!< GET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_DESCRIPTOR 0x0700u /*!< SET_DESCRIPTOR bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_CONFIGURATION 0x0880u /*!< GET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_CONFIGURATION 0x0900u /*!< SET_DEVICE_CONFIGURATION bmRequestType and bRequest word */ + +/* Standard request words for interface (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_INT_STATUS 0x0081u /*!< GET_INTERFACE_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_INT_FEATURE 0x0101u /*!< CLEAR_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INT_FEATURE 0x0301u /*!< SET_INTERFACE_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_GET_INTERFACE 0x0A81u /*!< GET_DEVICE_INTERFACE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_INTERFACE 0x0B01u /*!< SET_DEVICE_INTERFACE bmRequestType and bRequest word */ + +/* Standard request words for endpoint (bmRequestType | bRequest) */ +#define LDD_USB_STD_REQ_GET_EP_STATUS 0x0082u /*!< GET_ENDPOINT_STATUS bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_CLR_EP_FEATURE 0x0102u /*!< CLEAR_ENDPOINT_FEATURE bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SET_EP_FEATURE 0x0302u /*!< ENDPOINT_ bmRequestType and bRequest word */ +#define LDD_USB_STD_REQ_SYNCH_FRAME 0x0C12u /*!< SYNCH_DEVICE_FRAME bmRequestType and bRequest code */ + +#define LDD_USB_STATUS_DEVICE_SELF_POWERED_MASK 0x01u +#define LDD_USB_STATUS_DEVICE_REMOTE_WAKEUP_MASK 0x02u + +/* Standard descriptors */ +#define LDD_USB_DT_DEVICE 0x01u /*!< Device descriptor */ +#define LDD_USB_DT_CONFIGURATION 0x02u /*!< Configuration descriptor */ +#define LDD_USB_DT_STRING 0x03u /*!< String descriptor */ +#define LDD_USB_DT_INTERFACE 0x04u /*!< Interface descriptor */ +#define LDD_USB_DT_ENDPOINT 0x05u /*!< Endpoint descriptor */ +#define LDD_USB_DT_DEVICE_QUALIFIER 0x06u /*!< Device qualifier descriptor */ +#define LDD_USB_DT_OTHER_SPEED_CONFIGURATION 0x07u /*!< Other speed configuration descriptor */ +#define LDD_USB_DT_INTERFACE_POWER 0x08u /*!< Interface-level power management descriptor */ +#define LDD_USB_DT_OTG 0x09u /*!< OTG descriptor */ +#define LDD_USB_DT_DEBUG 0x0Au /*!< Debug descriptor */ +#define LDD_USB_DT_INTERFACE_ASSOCIATION 0x0Bu /*!< Interface association descriptor */ + +/* Standard feature selectors */ +#define LDD_USB_FEATURE_EP_HALT 0x00u /*!< Endpoint HALT feature selector */ +#define LDD_USB_FEATURE_DEV_REMOTE_WAKEUP 0x01u /*!< Remote Wake-up feature selector */ +#define LDD_USB_FEATURE_DEV_TEST_MODE 0x02u /*!< Test mode feature selector */ + +/*! Get decriptor request structure */ +typedef struct LDD_USB_TGetDecriptorRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bDescriptorIndex; /*!< Descriptor index */ + uint8_t bDescriptorType; /*!< Descriptor type */ + uint16_t wLanguageID; /*!< Language ID */ + uint16_t wLength; /*!< Requested data size */ +} LDD_USB_TGetDecriptorRequest; + +/*! Get endpoint status request structure */ +typedef struct LDD_USB_TEndpointStatusRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wValue; /*!< Not used, should be set to zero */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Reqested data size, should be set to 2 */ +} LDD_USB_TEndpointStatusRequest; + +/*! Clear/Set endpoint feature request structure */ +typedef struct LDD_USB_TEndpointFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint8_t bEndpoint; /*!< Endpoint address */ + uint8_t bIndexHigh; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TEndpointFeatureRequest; + +/*! Clear/Set interface request structure */ +typedef struct LDD_USB_TInterfaceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TInterfaceFeatureRequest; + +/*! Clear/Set device request structure */ +typedef struct LDD_USB_TDeviceFeatureRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wFeatureSelector; /*!< Feature selector */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TDeviceFeatureRequest; + +/*! Get interface request structure */ +typedef struct LDD_USB_TGetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wWalue; /*!< Not used, should be zero */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Reqested data size, should be set to 1 */ +} LDD_USB_TGetInterfaceRequest; + +/*! Set interface request structure */ +typedef struct LDD_USB_TSetInterfaceRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint16_t wAltSet; /*!< Alternate setting */ + uint16_t wInterface; /*!< Interface index */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetInterfaceRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetAddressRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t DeviceAddress; /*!< Device address */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetAddressRequest; + +/*! Set address request structure */ +typedef struct LDD_USB_TSetConfigRequest_Struct { + uint8_t bmRequestType; /*!< Characteristics of request */ + uint8_t bRequest; /*!< Request ID */ + uint8_t bValueHigh; /*!< Not used, should be set to zero */ + uint8_t ConfigNumber; /*!< Configuration number */ + uint16_t wIndex; /*!< Not used, should be set to zero */ + uint16_t wLength; /*!< Not used, should be set to zero */ +} LDD_USB_TSetConfigRequest; + +/* +** =================================================================== +** DAC device types and constants +** =================================================================== +*/ +#define LDD_DAC_OUTPUT_PIN_0 0x01u /*!< DAC output pin 0 mask */ + +#define LDD_DAC_ON_BUFFER_END 0x01U /*!< OnBufferEnd event mask */ +#define LDD_DAC_ON_BUFFER_START 0x02U /*!< OnBufferStart event mask */ +#define LDD_DAC_ON_BUFFER_WATERMARK 0x04U /*!< OnBufferWatermark event mask */ +#define LDD_DAC_ON_COMPLETE LDD_DMA_ON_COMPLETE /*!< OnComplete event mask */ +#define LDD_DAC_ON_ERROR LDD_DMA_ON_ERROR /*!< OnError event mask */ + +/*! Type specifying the DAC buffer work mode */ +typedef enum { + LDD_DAC_BUFFER_NORMAL_MODE = 0x00U, /*!< Normal (cyclic) mode */ + LDD_DAC_BUFFER_SWING_MODE = 0x01U, /*!< Swing mode */ + LDD_DAC_BUFFER_SCAN_MODE = 0x02U /*!< One-time scan mode */ +} LDD_DAC_TBufferMode; + +/*! Type specifying the DAC buffer watermark levels */ +typedef enum { + LDD_DAC_BUFFER_WATERMARK_L1 = 0x00U, + LDD_DAC_BUFFER_WATERMARK_L2 = 0x01U, + LDD_DAC_BUFFER_WATERMARK_L3 = 0x02U, + LDD_DAC_BUFFER_WATERMARK_L4 = 0x03U +} LDD_DAC_TBufferWatermark; + +#define LDD_DAC_DMA_ERROR 0x01u /*!< DMA error mask */ + +typedef void* LDD_DAC_TDataPtr; /*!< Type specifying the pointer to the DAC data variable */ +typedef uint32_t LDD_DAC_TData; /*!< The DAC data variable type */ +typedef uint32_t LDD_DAC_TErrorMask; /*!< Error mask */ +typedef uint32_t LDD_DAC_TArrayLength; /*!< Array length type */ + +/* +** =================================================================== +** FLASH device types and constants +** =================================================================== +*/ +#define LDD_FLASH_ON_OPERATION_COMPLETE 0x02u /*!< OnOperationComplete event mask */ +#define LDD_FLASH_ON_ERROR 0x04u /*!< OnError event mask */ + +#define LDD_FLASH_READ_COLLISION_ERROR 0x40u /*!< Read collision error flag's mask */ +#define LDD_FLASH_ACCESS_ERROR 0x20u /*!< Access error flag's mask */ +#define LDD_FLASH_PROTECTION_VIOLATION 0x10u /*!< Protection violation error flag's mask */ +#define LDD_FLASH_ERASE_VERIFICATION_ERROR 0x08u /*!< Erase verification error flag's mask */ +#define LDD_FLASH_MULTIPLE_WRITE_ERROR 0x04u /*!< Multiple write to one flash memory location error flag's mask */ + +/*! Type specifying HW commands for a flash device */ +typedef enum { + LDD_FLASH_READ_1S_BLOCK = 0x00u, /*!< Checks if an entire program flash or data flash logical block has been erased to the specified margin level */ + LDD_FLASH_READ_1S_SECTION = 0x01u, /*!< Checks if a section of program flash or data flash memory is erased to the specified read margin level */ + LDD_FLASH_WRITE_BYTE = 0x04u, /*!< Program byte */ + LDD_FLASH_WRITE_WORD = 0x05u, /*!< Program word */ + LDD_FLASH_WRITE_LONG_WORD = 0x06u, /*!< Program long word */ + LDD_FLASH_WRITE_PHRASE = 0x07u, /*!< Program phrase */ + LDD_FLASH_ERASE_FLASH_BLOCK = 0x08u, /*!< Erase flash memory block */ + LDD_FLASH_ERASE_SECTOR = 0x09u, /*!< Erase sector */ + LDD_FLASH_ERASE_ALL_FLASH_BLOCKS = 0x44u /*!< Erase all flash memory blocks */ +} LDD_FLASH_TCommand; + +/*! Type specifying possible FLASH component operation types */ +typedef enum { + LDD_FLASH_NO_OPERATION, /*!< No operation - initial state */ + LDD_FLASH_READ, /*!< Read operation */ + LDD_FLASH_WRITE, /*!< Write operation */ + LDD_FLASH_ERASE, /*!< Erase operation */ + LDD_FLASH_ERASE_BLOCK, /*!< Erase block operation */ + LDD_FLASH_VERIFY_ERASED_BLOCK /*!< Verify erased block operation */ +} LDD_FLASH_TOperationType; + +/*! Type specifying possible FLASH component operation states */ +typedef enum { + LDD_FLASH_FAILED = 0x00u, /*!< Operation has failed */ + LDD_FLASH_STOP = 0x01u, /*!< The operation has been stopped */ + LDD_FLASH_IDLE = 0x02u, /*!< No operation in progress */ + LDD_FLASH_STOP_REQ = 0x03u, /*!< The operation is in the STOP request mode */ + LDD_FLASH_START = 0x04u, /*!< Start of the operation, no operation steps have been done yet */ + LDD_FLASH_RUNNING = 0x05u /*!< Operation is in progress */ +} LDD_FLASH_TOperationStatus; + +typedef uint8_t LDD_FLASH_TErrorFlags; /*!< Type specifying FLASH component's error flags bit field */ + +typedef uint32_t LDD_FLASH_TAddress; /*!< Type specifying the Address parameter used by the FLASH component's methods */ + +typedef uint32_t LDD_FLASH_TDataSize; /*!< Type specifying the Size parameter used by the FLASH component's methods */ + +typedef uint16_t LDD_FLASH_TErasableUnitSize; /*!< Type specifying the Size output parameter of the GetErasableUnitSize method (pointer to a variable of this type is passed to the method) */ + +/*! Type specifying the FLASH component's rrror status information */ +typedef struct { + LDD_FLASH_TOperationType CurrentOperation; /*!< Current operation */ + LDD_FLASH_TCommand CurrentCommand; /*!< Last flash controller command */ + LDD_FLASH_TErrorFlags CurrentErrorFlags; /*!< Bitfield with error flags. See FLASH2.h for details */ + LDD_FLASH_TAddress CurrentAddress; /*!< Address of the flash memory location the error status is related to */ + LDD_TData *CurrentDataPtr; /*!< Pointer to current input data the error status is related to */ + LDD_FLASH_TDataSize CurrentDataSize; /*!< Size of the current input data to be programmed or erased in bytes */ +} LDD_FLASH_TErrorStatus; + +/* +** =================================================================== +** HSCMP device types and constants +** =================================================================== +*/ + +#define LDD_ANALOGCOMP_ON_COMPARE 0x01u /*!< OnCompare event mask */ + +/* Positive input pin masks */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_0_MASK 0x01U /*!< Mask for positive input pin 0 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_1_MASK 0x02U /*!< Mask for positive input pin 1 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_2_MASK 0x04U /*!< Mask for positive input pin 2 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_3_MASK 0x08U /*!< Mask for positive input pin 3 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_4_MASK 0x10U /*!< Mask for positive input pin 4 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_5_MASK 0x20U /*!< Mask for positive input pin 5 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_6_MASK 0x40U /*!< Mask for positive input pin 6 */ +#define LDD_ANALOGCOMP_POSITIVE_INPUT_7_MASK 0x80U /*!< Mask for positive input pin 7 */ + +/* Negative input pin masks */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_0_MASK 0x0100U /*!< Mask for negative input pin 0 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_1_MASK 0x0200U /*!< Mask for negative input pin 1 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_2_MASK 0x0400U /*!< Mask for negative input pin 2 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_3_MASK 0x0800U /*!< Mask for negative input pin 3 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_4_MASK 0x1000U /*!< Mask for negative input pin 4 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_5_MASK 0x2000U /*!< Mask for negative input pin 5 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_6_MASK 0x4000U /*!< Mask for negative input pin 6 */ +#define LDD_ANALOGCOMP_NEGATIVE_INPUT_7_MASK 0x8000U /*!< Mask for negative input pin 7 */ + +/* Output pin masks */ +#define LDD_ANALOGCOMP_OUTPUT_PIN_MASK 0x00010000U /*!< Mask for output pin */ + +/* Window Sample pin masks */ +#define LDD_ANALOGCOMP_WINDOWSAMPLE_PIN_MASK 0x00020000UL + +/*! Type specifying comparator input number */ +typedef enum { + LDD_ANALOGCOMP_INPUT_0 = 0x00U, /*!< Analog input 0 selected */ + LDD_ANALOGCOMP_INPUT_1 = 0x01U, /*!< Analog input 1 selected */ + LDD_ANALOGCOMP_INPUT_2 = 0x02U, /*!< Analog input 2 selected */ + LDD_ANALOGCOMP_INPUT_3 = 0x03U, /*!< Analog input 3 selected */ + LDD_ANALOGCOMP_INPUT_4 = 0x04U, /*!< Analog input 4 selected */ + LDD_ANALOGCOMP_INPUT_5 = 0x05U, /*!< Analog input 5 selected */ + LDD_ANALOGCOMP_INPUT_6 = 0x06U, /*!< Analog input 6 selected */ + LDD_ANALOGCOMP_INPUT_7 = 0x07U, /*!< Analog input 7 selected */ + LDD_ANALOGCOMP_INPUT_DISABLED = 0x08U /*!< Analog input disabled */ +} LDD_AnalogComp_TComparatorInput; + +/*! Type specifying current comparator output status */ +typedef enum { + LDD_ANALOGCOMP_NO_EDGE = 0x00U, /*!< No edge detected on output */ + LDD_ANALOGCOMP_FALLING_EDGE = 0x02U, /*!< Falling edge detected on output */ + LDD_ANALOGCOMP_RISING_EDGE = 0x04U, /*!< Rising edge detected on output */ + LDD_ANALOGCOMP_BOTH_EDGES = 0x06U /*!< Both edges detected on output */ +} LDD_AnalogComp_TCompareStatus; + +/*! Type specifying requested comparator mode */ +typedef enum { + LDD_ANALOGCOMP_RISING_EDGE_MODE = 0x10U, /*!< Rising edge detection */ + LDD_ANALOGCOMP_FALLING_EDGE_MODE = 0x08U, /*!< Falling edge detection */ + LDD_ANALOGCOMP_BOTH_EDGES_MODE = 0x18U /*!< Both edges detection */ +} LDD_AnalogComp_TComparatorMode; + +typedef uint8_t LDD_AnalogComp_TOutputValue; /*!< Type specifying comparator output value */ + +/* +** =================================================================== +** SDHC component types and constants +** =================================================================== +*/ + +#define LDD_SDHC_CARD_DATA_WIDTH_1_BIT 0x01u /*!< Card supports 1 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_4_BIT 0x02u /*!< Card supports 4 bit data bus */ +#define LDD_SDHC_CARD_DATA_WIDTH_8_BIT 0x04u /*!< Card supports 8 bit data bus */ +#define LDD_SDHC_CARD_BLOCK_READ 0x01u /*!< Card supports block reading */ +#define LDD_SDHC_CARD_BLOCK_WRITE 0x04u /*!< Card supports block writing */ +#define LDD_SDHC_CARD_ERASE 0x08u /*!< Card supports block erasion */ +#define LDD_SDHC_CARD_WRITE_PROTECTION 0x10u /*!< Card supports write protection */ +#define LDD_SDHC_CARD_IO 0x80u /*!< Card supports IO */ + +#define LDD_SDHC_CLK_PIN 0x01u /*!< SD clock pin mask */ +#define LDD_SDHC_CMD_PIN 0x02u /*!< SD command line pin mask */ +#define LDD_SDHC_DAT0_PIN 0x04u /*!< SD data line 0 pin mask */ +#define LDD_SDHC_DAT1_PIN 0x08u /*!< SD data line 1 pin mask */ +#define LDD_SDHC_DAT2_PIN 0x10u /*!< SD data line 2 pin mask */ +#define LDD_SDHC_DAT3_PIN 0x20u /*!< SD data line 3 pin mask */ +#define LDD_SDHC_DAT4_PIN 0x40u /*!< SD data line 4 pin mask */ +#define LDD_SDHC_DAT5_PIN 0x80u /*!< SD data line 5 pin mask */ +#define LDD_SDHC_DAT6_PIN 0x0100u /*!< SD data line 6 pin mask */ +#define LDD_SDHC_DAT7_PIN 0x0200u /*!< SD data line 7 pin mask */ +#define LDD_SDHC_CD_PIN 0x0400u /*!< SD card detection pin mask */ +#define LDD_SDHC_WP_PIN 0x0800u /*!< SD write protection pin mask */ +#define LDD_SDHC_LCTL_PIN 0x1000u /*!< SD LED control pin mask */ +#define LDD_SDHC_VS_PIN 0x2000u /*!< SD voltage control pin mask */ + +#define LDD_SDHC_ON_CARD_INSERTED 0x01u /*!< OnCardInserted event mask */ +#define LDD_SDHC_ON_CARD_REMOVED 0x02u /*!< OnCardRemoved event mask */ +#define LDD_SDHC_ON_FINISHED 0x04u /*!< OnFinished event mask */ + +/*! Card types */ +typedef enum { + LDD_SDHC_SD, /*!< Secure Digital memory card */ + LDD_SDHC_SDIO, /*!< Secure Digital IO card */ + LDD_SDHC_SDCOMBO, /*!< Combined Secure Digital memory and IO card */ + LDD_SDHC_MMC, /*!< MultiMediaCard memory card */ + LDD_SDHC_CE_ATA /*!< Consumer Electronics ATA card */ +} LDD_SDHC_TCardType; + +/*! Card access properties */ +typedef struct { + uint16_t MaxBlockLength; /*!< Max. transferable block length */ + bool MisalignBlock; /*!< Indicates if the data block can be spread over more than one physical block of the memory device */ + bool PartialBlock; /*!< Indicates whether partial block sizes can be used in block access */ +} LDD_SDHC_TCardAccess; + +/*! Card erasion properties */ +typedef struct { + uint16_t SectorSize; /*!< The size of an erasable unit */ + uint8_t Pattern; /*!< Memory content after erase */ +} LDD_SDHC_TCardErase; + +/*! Card write protection properties */ +typedef struct { + uint16_t GroupSize; /*!< The size of write protected group in number of erase groups */ + bool Permanent; /*!< Indicates whether card is permanently write protected (read-only) */ +} LDD_SDHC_TCardWriteProtect; + +/*! Card capabilities */ +typedef struct { + uint8_t DataWidths; /*!< Bit mask of supported data bus widths */ + uint8_t Operations; /*!< Bit mask of supported operations */ + bool HighSpeed; /*!< Indicates whether the card supports high clock configuration (SD bus clock frequency higher than about 25MHz) */ + bool HighCapacity; /*!< Indicates whether the card requires block addressing instead of byte addressing */ + bool LowVoltage; /*!< Indicates whether the card supports the host's low voltage range */ + LDD_SDHC_TCardAccess Read; /*!< Card data read access capabilities */ + LDD_SDHC_TCardAccess Write; /*!< Card data write access capabilities */ + LDD_SDHC_TCardErase Erase; /*!< Card data erasion capabilities */ + LDD_SDHC_TCardWriteProtect WriteProtect; /*!< Write protection properties */ +} LDD_SDHC_TCardCaps; + +/*! Card features description */ +typedef struct { + LDD_SDHC_TCardType Type; /*!< Card type */ + uint16_t BlockLength; /*!< Physical memory block length */ + uint32_t BlockCount; /*!< Number of physical memory blocks */ + LDD_SDHC_TCardCaps Caps; /*!< Card capabilities */ +} LDD_SDHC_TCardInfo; + +/*! Transfer operations */ +typedef enum { + LDD_SDHC_READ, /*!< Read operation */ + LDD_SDHC_WRITE /*!< Write operation */ +} LDD_SDHC_TTransferOperation; + +/*! Transfer buffer descriptor */ +typedef struct { + uint16_t Size; /*!< Buffer data size */ + uint8_t *DataPtr; /*!< Pointer to buffer data */ +} LDD_SDHC_TBufferDesc; + +/*! Voltage options */ +typedef enum { + LDD_SDHC_LOW_VOLTAGE, /*!< Low voltage */ + LDD_SDHC_HIGH_VOLTAGE /*!< High voltage */ +} LDD_SDHC_TVoltage; + +/*! Write protection types */ +typedef enum { + LDD_SDHC_GROUP, /*!< Write protection by groups */ + LDD_SDHC_CARD /*!< Whole card write protection */ +} LDD_SDHC_TWriteProtectType; + +/*! Component states */ +typedef enum { + LDD_SDHC_DISABLED, /*!< Disabled */ + LDD_SDHC_RESET, /*!< Resetting card */ + LDD_SDHC_IDLE, /*!< Idling */ + LDD_SDHC_VOLTAGE_VALIDATION, /*!< Validating voltage */ + LDD_SDHC_CARD_REGISTRATION, /*!< Registrating card */ + LDD_SDHC_CARD_SELECTION, /*!< Selecting card */ + LDD_SDHC_CARD_INFO_RETRIEVAL, /*!< Retrieving card info */ + LDD_SDHC_TRANSFER, /*!< Transferring data */ + LDD_SDHC_ERASION, /*!< Erasing blocks */ + LDD_SDHC_IO_REG_TRANSFER, /*!< Transferring IO registers */ + LDD_SDHC_DATA_WIDTH_SELECTION, /*!< Selecting data width */ + LDD_SDHC_BUS_CLOCK_SELECTION, /*!< Selecting bus clock */ + LDD_SDHC_WRITE_PROTECTION_SETUP, /*!< Setting up write protection */ + LDD_SDHC_WRITE_PROTECTION_RETRIEVAL /*!< Retrieving write protection configuration */ +} LDD_SDHC_TStatus; + +/*! Operation completion error codes */ +typedef enum { + LDD_SDHC_ERR_OK, /*!< No error */ + LDD_SDHC_ERR_DMA, /*!< DMA or block size error */ + LDD_SDHC_ERR_NOT_SUPPORTED, /*!< Initiated operation is not supported by the card (supported operations are contained in the card information structure) */ + LDD_SDHC_ERR_TIMEOUT, /*!< Command or data timeout */ + LDD_SDHC_ERR_COMMAND_CRC, /*!< Command CRC check failed */ + LDD_SDHC_ERR_DATA_CRC, /*!< Data CRC check failed */ + LDD_SDHC_ERR_ADDRESS_OUT_OF_RANGE, /*!< The card address is beyond the card capacity */ + LDD_SDHC_ERR_ADDRESS_MISALIGN, /*!< The card address does not align with physical blocks of the card */ + LDD_SDHC_ERR_BLOCK_LEN_ERROR, /*!< Block length exceeds the maximum value for the card */ + LDD_SDHC_ERR_WP_VIOLATION, /*!< Attempt to program a write protected block */ + LDD_SDHC_ERR_CARD_IS_LOCKED, /*!< The card is locked by the host */ + LDD_SDHC_ERR_WP_ERASE_SKIP, /*!< Only partial address space was erased due to existing write protected blocks */ + LDD_SDHC_ERR_INTERNAL_FAILURE, /*!< Internal component error */ + LDD_SDHC_ERR_CARD_FAILURE /*!< The card was unable to complete the operation */ +} LDD_SDHC_TError; + +/* +** =================================================================== +** DMA device types and constants +** =================================================================== +*/ + +#define LDD_DMA_ON_COMPLETE 0x01U /*!< OnTransferComplete event mask. */ +#define LDD_DMA_ON_ERROR 0x02U /*!< OnError event mask. */ + +#define LDD_DMA_UNKNOWN_ERROR 0x80000000U /*!< Unknown error. */ +#define LDD_DMA_CHANNEL_PRIORITY_ERROR 0x4000U /*!< Channel priority error. */ +#define LDD_DMA_SOURCE_ADDRESS_ERROR 0x80U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_SOURCE_OFFSET_ERROR 0x40U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_ADDRESS_ERROR 0x20U /*!< Address inconsistency with transfer size error. */ +#define LDD_DMA_DESTINATION_OFFSET_ERROR 0x10U /*!< Offset inconsistency with transfer size error. */ +#define LDD_DMA_COUNT_ERROR 0x08U /*!< Byte count inconsistency with transfer sizes or transfer count error. */ +#define LDD_DMA_SCATTER_GATHER_ERROR 0x04U /*!< Scatter/gather configuration error. */ +#define LDD_DMA_SOURCE_BUS_ERROR 0x02U /*!< Bus error on a source read. */ +#define LDD_DMA_DESTINATION_BUS_ERROR 0x01U /*!< Bus error on a destination write. */ + +#define LDD_DMA_CHANNEL_0_MASK 0x01UL /*!< DMA channel 0 mask. */ +#define LDD_DMA_CHANNEL_1_MASK 0x02UL /*!< DMA channel 1 mask. */ +#define LDD_DMA_CHANNEL_2_MASK 0x04UL /*!< DMA channel 2 mask. */ +#define LDD_DMA_CHANNEL_3_MASK 0x08UL /*!< DMA channel 3 mask. */ +#define LDD_DMA_CHANNEL_4_MASK 0x10UL /*!< DMA channel 4 mask. */ +#define LDD_DMA_CHANNEL_5_MASK 0x20UL /*!< DMA channel 5 mask. */ +#define LDD_DMA_CHANNEL_6_MASK 0x40UL /*!< DMA channel 6 mask. */ +#define LDD_DMA_CHANNEL_7_MASK 0x80UL /*!< DMA channel 7 mask. */ +#define LDD_DMA_CHANNEL_8_MASK 0x0100UL /*!< DMA channel 8 mask. */ +#define LDD_DMA_CHANNEL_9_MASK 0x0200UL /*!< DMA channel 9 mask. */ +#define LDD_DMA_CHANNEL_10_MASK 0x0400UL /*!< DMA channel 10 mask. */ +#define LDD_DMA_CHANNEL_11_MASK 0x0800UL /*!< DMA channel 11 mask. */ +#define LDD_DMA_CHANNEL_12_MASK 0x1000UL /*!< DMA channel 12 mask. */ +#define LDD_DMA_CHANNEL_13_MASK 0x2000UL /*!< DMA channel 13 mask. */ +#define LDD_DMA_CHANNEL_14_MASK 0x4000UL /*!< DMA channel 14 mask. */ +#define LDD_DMA_CHANNEL_15_MASK 0x8000UL /*!< DMA channel 15 mask. */ +#define LDD_DMA_CHANNEL_16_MASK 0x00010000UL /*!< DMA channel 16 mask. */ +#define LDD_DMA_CHANNEL_17_MASK 0x00020000UL /*!< DMA channel 17 mask. */ +#define LDD_DMA_CHANNEL_18_MASK 0x00040000UL /*!< DMA channel 18 mask. */ +#define LDD_DMA_CHANNEL_19_MASK 0x00080000UL /*!< DMA channel 19 mask. */ +#define LDD_DMA_CHANNEL_20_MASK 0x00100000UL /*!< DMA channel 21 mask. */ +#define LDD_DMA_CHANNEL_21_MASK 0x00200000UL /*!< DMA channel 22 mask. */ +#define LDD_DMA_CHANNEL_22_MASK 0x00400000UL /*!< DMA channel 23 mask. */ +#define LDD_DMA_CHANNEL_23_MASK 0x00800000UL /*!< DMA channel 24 mask. */ +#define LDD_DMA_CHANNEL_24_MASK 0x01000000UL /*!< DMA channel 25 mask. */ +#define LDD_DMA_CHANNEL_25_MASK 0x02000000UL /*!< DMA channel 26 mask. */ +#define LDD_DMA_CHANNEL_26_MASK 0x04000000UL /*!< DMA channel 27 mask. */ +#define LDD_DMA_CHANNEL_27_MASK 0x08000000UL /*!< DMA channel 28 mask. */ +#define LDD_DMA_CHANNEL_28_MASK 0x10000000UL /*!< DMA channel 29 mask. */ +#define LDD_DMA_CHANNEL_29_MASK 0x20000000UL /*!< DMA channel 30 mask. */ +#define LDD_DMA_CHANNEL_30_MASK 0x40000000UL /*!< DMA channel 31 mask. */ +#define LDD_DMA_CHANNEL_31_MASK 0x80000000UL /*!< DMA channel 32 mask. */ + +/* Action executed after request and transfer service completes */ +#define LDD_DMA_NO_ACTION 0x00U /*!< No action performed after request serviced. */ +#define LDD_DMA_DESTINATION_ADDRESS_ADJUSTMENT 0x01U /*!< Destination address adjustment after request serviced. */ +#define LDD_DMA_SOURCE_ADDRESS_ADJUSTMENT 0x02U /*!< Source address adjustment after request serviced. */ +#define LDD_DMA_ADDRESS_ADJUSTMENT 0x01U /*!< Address adjustment after transfer completed. */ +#define LDD_DMA_SCATTER_GATHER 0x02U /*!< Scatter/gather performed after transfer completed. */ + +typedef void LDD_DMA_TData; +typedef uint8_t LDD_DMA_TTransactionSize; /* Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TTransactionCount; +typedef uint32_t LDD_DMA_TRequestCount; +typedef uint32_t LDD_DMA_TTransferDataSize; + +typedef uint32_t LDD_DMA_TAddress; /*!< Type specifying the address parameter used by the DMA component's methods. */ +typedef int32_t LDD_DMA_TAddressOffset; /*!< Type specifying the address signed offset parameter used by the DMA component's methods. */ +typedef uint32_t LDD_DMA_TByteCount; /*!< Type specifying the byte count/minor loop count parameter used by the DMA component's methods. */ +typedef uint8_t LDD_DMA_TTransferSize; /*!< Type specifying the transfer size parameter used by the DMA component's methods. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TModuloSize; /*!< Type specifying the modulo size parameter used by the DMA component's methods. */ + /*!< This value power of two represents size of used circular buffer (0U - buffer disabled). See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TTriggerSource; /*!< Type specifying the trigger source signal number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TChannelNumber; /*!< Type specifying the DMA channel number. See the MCU manual for detail description of allowed values. */ +typedef uint8_t LDD_DMA_TRecordNumber; /*!< Type specifying the DMA descriptor record number. */ +typedef uint32_t LDD_DMA_TChannelMask; /*!< Type specifying the DMA channel mask. For possible values see channel mask constants. */ +typedef uint8_t LDD_DMA_TChannelPriority; /*!< Type specifying the DMA channel priority number. See the MCU manual for detail description of allowed values. */ +typedef uint16_t LDD_DMA_TOuterLoopCount; /*!< Type specifying the transfer outer/major loop count. */ +typedef uint8_t LDD_DMA_TAfterRequest; /*!< Type specifying the operation executed after request service is completed. */ +typedef uint8_t LDD_DMA_TAfterTransfer; /*!< Type specifying the operation executed after transfer service is completed. */ +typedef uint8_t LDD_DMA_TBandwidthControl; /*!< Type specifying the bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ +typedef uint32_t LDD_DMA_TErrorFlags; /*!< DMA controller error flags. See the DMA_LDD component's header file for detail description of allowed values. */ + +/*! Type specifying a DMA channel status. */ +typedef enum { + LDD_DMA_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_DONE, /*!< Transfer is completed, waiting to start of next transfer. */ + LDD_DMA_ERROR /*!< Error detected. */ +} LDD_DMA_TChannelStatus; + +/*! Type specifying a DMA transfer state. */ +typedef enum { + LDD_DMA_TRANSFER_IDLE, /*!< Channel is idle, no request is serviced nor transfer completed. */ + LDD_DMA_TRANSFER_BUSY, /*!< Channel is active, request is serviced. */ + LDD_DMA_TRANSFER_ERROR /*!< Error detected. */ +} LDD_DMA_TTransferState; + +/*! Type specifying the DMA transfer mode. */ +typedef enum { + LDD_DMA_CYCLE_STEAL_TRANSFERS, /*!< Only single read/write transfer is done per one service request. */ + LDD_DMA_SINGLE_TRANSFER, /*!< Transfer of all bytes defined by Data size is done after single service request. */ + LDD_DMA_NESTED_TRANSFERS /*!< Sequence of transfers triggered by service requests. One request transfers number of bytes defined by Byte count value. */ +} LDD_DMA_TTransferMode; + +/*! Type specifying the DMA trigger source type. */ +typedef enum { + LDD_DMA_SW_TRIGGER, /*!< Explicit software trigger. */ + LDD_DMA_HW_TRIGGER, /*!< Peripheral device trigger. */ + LDD_DMA_ALWAYS_ENABLED_TRIGGER /*!< Always enabled trigger. */ +} LDD_DMA_TTriggerType; + +/*! Type specifying the DMA error information structure. */ +typedef struct { + LDD_DMA_TChannelNumber ChannelNumber; /*!< Last error recorded channel number. */ + LDD_DMA_TErrorFlags ErrorFlags; /*!< Channel error flags. */ +} LDD_DMA_TError; + +/*! Type specifying the DMA Transfer descriptor information structure. */ +typedef struct { + LDD_TUserData *UserDataPtr; /*!< User device data structure pointer to be returned by the DMA_LDD component's ISR to the dynamic callback of this transfer descriptor. */ + LDD_DMA_TAddress SourceAddress; /*!< Address of a DMA transfer source data. */ + LDD_DMA_TAddressOffset SourceAddressOffset; /*!< Offset to be added to the source address after each elemental read operation. */ + LDD_DMA_TTransferSize SourceTransferSize; /*!< Source data transfer size (size of a elemental read operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize SourceModuloSize; /*!< Source address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TAddress DestinationAddress; /*!< Address of a DMA transfer destination. */ + LDD_DMA_TAddressOffset DestinationAddressOffset; /*!< Offset to be added to the destination address after each elemental write operation. */ + LDD_DMA_TTransferSize DestinationTransferSize; /*!< Destination data transfer size (size of a elemental write operation). See the DMA_PDD header file for detail description of allowed values. */ + LDD_DMA_TModuloSize DestinationModuloSize; /*!< Destination address modulo size. For the description of allowed values see the LDD_DMA_TModuloSize type declaration. */ + LDD_DMA_TTransferMode TransferMode; /*!< Selects DMA transfer mode. For the description of allowed values see the LDD_DMA_TTransferMode type declaration. */ + LDD_DMA_TByteCount ByteCount; /*!< Size of data in bytes to be transferred in single transfer. */ + LDD_DMA_TOuterLoopCount OuterLoopCount; /*!< Number of the outer loop iteration in the Nested operation mode, otherwise should have value of one. */ + bool InnerLoopChannelLink; /*!< TRUE - Inner loop channel linking enabled (if the nested operation is used, then this item enables the minor (inner) loop channel linking). */ + LDD_DMA_TChannelNumber InnerLoopLinkedChannel; /*!< Linked DMA channel number (used only if the InnerLoopChannelLink item is set TRUE) */ + bool OuterLoopChannelLink; /*!< TRUE - Outer (major) loop channel linking is enabled. Enables channel linking after transfer completes. */ + LDD_DMA_TChannelNumber OuterLoopLinkedChannel; /*!< Outer (major) loop linked DMA channel number (used only if the OuterLoopChannelLink item is set TRUE). */ + LDD_DMA_TAfterRequest AfterRequestComplete; /*!< Type of an action after the elemental read/write operation is done. For the description of allowed values see the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAddressOffset AddressOffset; /*!< Address offset value. Address specified in AfterRequestComplete item is adjusted by stored value. See the LDD_DMA_TAfterRequest type declaration. */ + LDD_DMA_TAfterTransfer AfterTransferComplete; /*!< Type of an action executed after the last transfer operation is done. For the description of allowed values see the LDD_DMA_TAfterTransfer type declaration. */ + LDD_DMA_TAddressOffset SourceAddressAdjustment; /*!< Source address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddressOffset DestinationAddressAdjustment; /*!< Destination address adjustment value. Used only if the AfterTransferComplete item is set to LDD_DMA_ADDRESS_ADJUSTMENT. */ + LDD_DMA_TAddress ScatterGatherAddress; /*!< Scatter / gather address. Used only if the AfterTransferComplete item is set to LDD_DMA_SCATTER_GATHER. */ + LDD_DMA_TBandwidthControl BandwidthControl; /*!< DMA channel bandwidth control. See the DMA_PDD header file for detail description of allowed values. */ + bool ChannelAutoSelection; /*!< TRUE - DMA channel autoselection engine is used. FALSE - DMA fixed channel is used. */ + LDD_DMA_TChannelNumber ChannelNumber; /*!< If ChannelAutoSelection is FALSE this item contains fixed channel number. If ChannelAutoSelection is TRUE then after allocation this item is filled by autoselected channel number. */ + LDD_DMA_TTriggerType TriggerType; /*!< DMA transfer trigger type. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + LDD_DMA_TTriggerSource TriggerSource; /*!< Trigger source number. For the description of allowed values see the LDD_DMA_TBTriggerType declaration. */ + bool PeriodicTrigger; /*!< TRUE - periodic trigger is required, FALSE - periodic trigger is not required. */ + bool DisableAfterRequest; /*!< TRUE - DMA transfer request is automatically disabled after transfer complete. */ + bool Interrupts; /*!< TRUE - interrupts are requested. */ + bool OnComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnHalfComplete; /*!< TRUE - event is enabled during initialization. */ + bool OnError; /*!< TRUE - event is enabled during initialization. */ + void (*OnCompleteEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnComplete event, NULL if event is not used. */ + void (*OnErrorEventPtr)(LDD_TUserData* UserDataPtr); /*!< Pointer to the OnError event, NULL if event is not used. */ + bool ChannelEnabled; /*!< TRUE - DMA channel is allocated and used by DMATransfer component. */ +} LDD_DMA_TTransferDescriptor; + +typedef LDD_DMA_TTransferDescriptor *LDD_DMA_TTransferDescriptorPtr; /*!< Type specifying address of the DMA Transfer descriptor structure. */ + +/* +** =================================================================== +** SPI device types and constants - SPIMaster_LDD +** =================================================================== +*/ + +#define LDD_SPIMASTER_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPIMASTER_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPIMASTER_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPIMASTER_CS_0_PIN 0x08U /*!< Chip select 0 pin mask */ +#define LDD_SPIMASTER_CS_1_PIN 0x10U /*!< Chip select 1 pin mask */ +#define LDD_SPIMASTER_CS_2_PIN 0x20U /*!< Chip select 2 pin mask */ +#define LDD_SPIMASTER_CS_3_PIN 0x40U /*!< Chip select 3 pin mask */ +#define LDD_SPIMASTER_CS_4_PIN 0x80U /*!< Chip select 4 pin mask */ +#define LDD_SPIMASTER_CS_5_PIN 0x0100U /*!< Chip select 5 pin mask */ +#define LDD_SPIMASTER_CS_6_PIN 0x0200U /*!< Chip select 6 pin mask */ +#define LDD_SPIMASTER_CS_7_PIN 0x0400U /*!< Chip select 7 pin mask */ +#define LDD_SPIMASTER_CSS_PIN 0x0800U /*!< Chip select strobe pin mask */ + +#define LDD_SPIMASTER_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPIMASTER_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPIMASTER_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPIMASTER_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPIMASTER_PARITY_ERROR 0x02U /*!< Parity error */ +#define LDD_SPIMASTER_RX_DMA_ERROR 0x04U /*!< Receive DMA channel error */ +#define LDD_SPIMASTER_TX_DMA_ERROR 0x08U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPIMASTER_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ +} LDD_SPIMASTER_TStats; + +/* +** =================================================================== +** SPI device types and constants - SPISlave_LDD +** =================================================================== +*/ + +#define LDD_SPISLAVE_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SPISLAVE_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SPISLAVE_CLK_PIN 0x04U /*!< Clock pin mask */ +#define LDD_SPISLAVE_SS_PIN 0x08U /*!< Slave select pin mask */ + +#define LDD_SPISLAVE_ON_BLOCK_RECEIVED 0x01U /*!< OnBlockReceived event mask */ +#define LDD_SPISLAVE_ON_BLOCK_SENT 0x02U /*!< OnBlockSent event mask */ +#define LDD_SPISLAVE_ON_ERROR 0x04U /*!< OnError event mask */ + +#define LDD_SPISLAVE_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SPISLAVE_TX_UNDERFLOW 0x02U /*!< Transmitter underflow */ +#define LDD_SPISLAVE_PARITY_ERROR 0x04U /*!< Parity error */ +#define LDD_SPISLAVE_RX_DMA_ERROR 0x08U /*!< Receive DMA channel error */ +#define LDD_SPISLAVE_TX_DMA_ERROR 0x10U /*!< Transmit DMA channel error */ + +typedef uint32_t LDD_SPISLAVE_TError; /*!< Communication error type */ + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxParityErrors; /*!< Number of receiver parity errors, which have occured */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ +} LDD_SPISLAVE_TStats; + +/* +** =================================================================== +** I2S device types and constants +** =================================================================== +*/ + +#define LDD_SSI_INPUT_PIN 0x01U /*!< Input pin mask */ +#define LDD_SSI_OUTPUT_PIN 0x02U /*!< Output pin mask */ +#define LDD_SSI_RX_CLK_PIN 0x04U /*!< Rx clock pin mask */ +#define LDD_SSI_TX_CLK_PIN 0x08U /*!< Tx clock pin mask */ +#define LDD_SSI_RX_FS_PIN 0x10U /*!< Rx frame sync pin mask */ +#define LDD_SSI_TX_FS_PIN 0x20U /*!< Tx frame sync pin mask */ +#define LDD_SSI_MCLK_PIN 0x40U /*!< Master clock pin mask */ +#define LDD_SSI_INPUT_PIN_CHANNEL_0 0x80U /*!< Input pin mask for data channel 0 */ +#define LDD_SSI_INPUT_PIN_CHANNEL_1 0x0100U /*!< Input pin mask for data channel 1 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_0 0x0200U /*!< Output pin mask for data channel 0 */ +#define LDD_SSI_OUTPUT_PIN_CHANNEL_1 0x0400U /*!< Output pin mask for data channel 1 */ + +#define LDD_SSI_ON_BLOCK_RECEIVED 0x01u /*!< OnBlockReceived event mask */ +#define LDD_SSI_ON_BLOCK_SENT 0x02u /*!< OnBlockSent event mask */ +#define LDD_SSI_ON_ERROR 0x04u /*!< OnError event mask */ +#define LDD_SSI_ON_BLOCK_RECEIVED_1 0x08u /*!< OnBlockReceived event mask for second channel */ +#define LDD_SSI_ON_BLOCK_SENT_1 0x10u /*!< OnBlockSent event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_FRAME_SYNC 0x20u /*!< OnReceiveFrameSync event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_FRAME_SYNC 0x40u /*!< OnTransmitFrameSync event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_LAST_SLOT 0x80u /*!< OnReceiveLastSlot event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_LAST_SLOT 0x0100u /*!< OnTransmitLastSlot event mask for second channel */ +#define LDD_SSI_ON_RECEIVE_COMPLETE 0x0200u /*!< OnReceiveComplete event mask for second channel */ +#define LDD_SSI_ON_TRANSMIT_COMPLETE 0x0400u /*!< OnTransmitComplete event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_TAG_UPDATED 0x0800u /*!< OnAC97TagUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_ADDRESS_UPDATED 0x1000u /*!< OnAC97CommandAddressUpdated event mask for second channel */ +#define LDD_SSI_ON_A_C_9_7_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ +#define LDD_SSI_ON_AC_97_COMMAND_DATA_UPDATED 0x2000u /*!< OnAC97CommandDataUpdated event mask for second channel */ + +#define LDD_SSI_RECEIVER 0x01U /*!< Receive section of the device. */ +#define LDD_SSI_TRANSMITTER 0x02U /*!< Transmit section of the device. */ + +#define LDD_SSI_RX_OVERFLOW 0x01U /*!< Receiver overflow */ +#define LDD_SSI_RX_OVERFLOW_1 0x02U /*!< Receiver overflow 1 */ +#define LDD_SSI_RX_SYNC_ERROR 0x04U /*!< Receiver frame sync error */ +#define LDD_SSI_RX_DMA_ERROR 0x08U /*!< Receiver DMA error */ + +#define LDD_SSI_TX_UNDERFLOW 0x10U /*!< Transmitter underflow */ +#define LDD_SSI_TX_UNDERFLOW_1 0x20U /*!< Transmitter underflow 1 */ +#define LDD_SSI_TX_SYNC_ERROR 0x40U /*!< Transmitter frame sync error */ +#define LDD_SSI_TX_DMA_ERROR 0x80U /*!< Transmitter DMA error */ + +#define LDD_SSI_RX_FRAME_COMPLETE 0x01U /*!< Receive frame is finished after disabling transfer */ +#define LDD_SSI_TX_FRAME_COMPLETE 0x02U /*!< Transmit frame is finished after disabling transfer */ +#define LDD_SSI_RX_FRAME_SYNC 0x04U /*!< Receiver frame sync */ +#define LDD_SSI_TX_FRAME_SYNC 0x08U /*!< Transmit frame sync */ +#define LDD_SSI_RX_LAST_SLOT 0x10U /*!< Receive last time slot */ +#define LDD_SSI_TX_LAST_SLOT 0x20U /*!< Transmit last time slot */ +#define LDD_SSI_AC97_TAG 0x40U /*!< AC97 tag updated */ +#define LDD_SSI_AC97_COMMAND_ADDRESS 0x80U /*!< AC97 command address updated */ +#define LDD_SSI_AC97_COMMAND_DATA 0x0100U /*!< AC97 command data updated */ + +typedef uint8_t LDD_SSI_TSectionMask; /*!< Device section type */ + +typedef uint32_t LDD_SSI_TError; /*!< Communication error type */ + +typedef uint32_t LDD_SSI_TComStatus; /*!< Communication status type */ + +/*! Group of pointers to data blocks. */ +typedef struct { + LDD_TData *Channel0Ptr; /*!< Pointer to data block to send/received via data channel 0 */ + LDD_TData *Channel1Ptr; /*!< Pointer to data block to send/received via data channel 1 */ +} LDD_SSI_TDataBlocks; + +/*! Command type */ +typedef enum { + LDD_SSI_READ_COMMAND = 0x08u, + LDD_SSI_WRITE_COMMAND = 0x10u +} LDD_SSI_TAC97CommandType; + +/*! AC97 command */ +typedef struct { + LDD_SSI_TAC97CommandType Type; /*!< Command type */ + uint32_t Address; /*!< Command address */ + uint32_t Data; /*!< Command data */ +} LDD_SSI_TAC97Command; + +/*! Communication statistics */ +typedef struct { + uint32_t RxChars; /*!< Number of received characters */ + uint32_t TxChars; /*!< Number of transmitted characters */ + uint32_t RxOverruns; /*!< Number of receiver overruns, which have occured */ + uint32_t TxUnderruns; /*!< Number of transmitter underruns, which have occured */ + uint32_t RxChars1; /*!< Number of received characters for second channel */ + uint32_t TxChars1; /*!< Number of transmitted characters for second channel */ + uint32_t RxOverruns1; /*!< Number of receiver overruns, which have occured for second channel */ + uint32_t TxUnderruns1; /*!< Number of transmitter underruns, which have occured for second channel */ +} LDD_SSI_TStats; + +/* +** =================================================================== +** RTC device types and constants +** =================================================================== +*/ + +#define LDD_RTC_ON_SECOND 0x10u /*!< OnSecond event mask */ +#define LDD_RTC_ON_MONOTONIC_OVERFLOW 0x08u /*!< OnMonotonicCounter event mask */ +#define LDD_RTC_ON_ALARM 0x04u /*!< OnAlarm event mask */ +#define LDD_RTC_ON_TIME_OVERFLOW 0x02u /*!< OnTimeOverflow event mask */ +#define LDD_RTC_ON_TIME_INVALID 0x01u /*!< OnTimeInvalid event mask */ +#define LDD_RTC_ON_STOPWATCH 0x0100u /*!< OnStopwatch event mask */ + +/*! Structure used for time operation */ +typedef struct { + uint32_t Second; /*!< seconds (0 - 59) */ + uint32_t Minute; /*!< minutes (0 - 59) */ + uint32_t Hour; /*!< hours (0 - 23) */ + uint32_t DayOfWeek; /*!< day of week (0-Sunday, .. 6-Saturday) */ + uint32_t Day; /*!< day (1 - 31) */ + uint32_t Month; /*!< month (1 - 12) */ + uint32_t Year; /*!< year */ +} LDD_RTC_TTime; + + + +/* +** =================================================================== +** CRC device types and constants +** =================================================================== +*/ + +#define LDD_CRC_16_SEED_LOW 0x00U /*!< CRC 16bit seed low */ +#define LDD_CRC_16_POLY_LOW 0x8005U /*!< CRC 16bit poly low */ +#define LDD_CRC_32_SEED_LOW 0xFFFFU /*!< CRC 32bit seed low */ +#define LDD_CRC_32_SEED_HIGH 0xFFFFU /*!< CRC 32bit seed high */ +#define LDD_CRC_32_POLY_LOW 0x1DB7U /*!< CRC 32bit poly low */ +#define LDD_CRC_32_POLY_HIGH 0x04C1U /*!< CRC 32bit poly high */ +#define LDD_CRC_CCITT_SEED_LOW 0xFFFFU /*!< CRC CCITT seed low */ +#define LDD_CRC_CCITT_POLY_LOW 0x1021U /*!< CRC CCITT poly low */ +#define LDD_CRC_MODBUS_16_SEED_LOW 0xFFFFU /*!< CRC MODBUS16 seed low */ +#define LDD_CRC_MODBUS_16_POLY_LOW 0x8005U /*!< CRC MODBUS16 poly low */ +#define LDD_CRC_KERMIT_SEED_LOW 0x00U /*!< CRC KERMIT seed low */ +#define LDD_CRC_KERMIT_POLY_LOW 0x1021U /*!< CRC KERMIT poly low */ +#define LDD_CRC_DNP_SEED_LOW 0x00U /*!< CRC DNP seed low */ +#define LDD_CRC_DNP_POLY_LOW 0x3D65U /*!< CRC DNP poly low */ + +/*! Transpose type */ +typedef enum { + LDD_CRC_NO_TRANSPOSE = 0, /*!< No transposition */ + LDD_CRC_BITS = 1, /*!< Bits are transposed */ + LDD_CRC_BITS_AND_BYTES = 2, /*!< Bits and bytes are transposed */ + LDD_CRC_BYTES = 3 /*!< Bytes are transposed */ +} LDD_CRC_TTransposeType; + +/*! CRC standard */ +typedef enum { + LDD_CRC_16, /*!< CRC16 standard */ + LDD_CRC_CCITT, /*!< CCITT standard */ + LDD_CRC_MODBUS_16, /*!< MODBUS16 standard */ + LDD_CRC_KERMIT, /*!< KERMIT standard */ + LDD_CRC_DNP, /*!< DNP standard */ + LDD_CRC_32, /*!< CRC32 standard */ + LDD_CRC_USER /*!< User defined type */ +} LDD_CRC_TCRCStandard; + +/*! User CRC standard */ +typedef struct { + bool Width32bit; /*!< 32bit CRC? */ + bool ResultXORed; /*!< Result XORed? */ + uint16_t SeedLow; /*!< Seed low value */ + uint16_t SeedHigh; /*!< Seed high value */ + uint16_t PolyLow; /*!< Poly low value */ + uint16_t PolyHigh; /*!< Poly high value */ + LDD_CRC_TTransposeType InputTransposeMode; /*!< Input transpose type */ + LDD_CRC_TTransposeType OutputTransposeMode; /*!< Output transpose type */ +} LDD_CRC_TUserCRCStandard; + +/* +** =================================================================== +** RNG device types and constants +** =================================================================== +*/ + + +#define LDD_RNG_LFSR_ERROR 0x01U /*!< Linear feedback shift register error */ +#define LDD_RNG_OSCILLATOR_ERROR 0x02U /*!< Oscillator error */ +#define LDD_RNG_SELF_TEST_ERROR 0x04U /*!< Self test error */ +#define LDD_RNG_STATISTICAL_ERROR 0x08U /*!< LStatistical test error */ +#define LDD_RNG_FIFO_UNDERFLOW_ERROR 0x10U /*!< FIFO underflow error */ + +#define LDD_RNG_SELF_TETS_RESEED_ERROR 0x00200000U /*!< Reseed self test fail */ +#define LDD_RNG_SELF_TEST_PRNG_ERROR 0x00400000U /*!< PRNG self test fail */ +#define LDD_RNG_SELF_TEST_TRNG_ERROR 0x00800000U /*!< TRNG self test fail */ +#define LDD_RNG_MONOBIT_TEST_ERROR 0x01000000U /*!< Monobit test fail */ +#define LDD_RNG_LENGTH_1_RUN_TEST_ERROR 0x02000000U /*!< Length 1 run test fail */ +#define LDD_RNG_LENGTH_2_RUN_TEST_ERROR 0x04000000U /*!< Length 2 run test fail */ +#define LDD_RNG_LENGTH_3_RUN_TEST_ERROR 0x08000000U /*!< Length 3 run test fail */ +#define LDD_RNG_LENGTH_4_RUN_TEST_ERROR 0x10000000U /*!< Length 4 run test fail */ +#define LDD_RNG_LENGTH_5_RUN_TEST_ERROR 0x20000000U /*!< Length 5 run test fail */ +#define LDD_RNG_LENGTH_6_RUN_TEST_ERROR 0x40000000U /*!< Length 6 run test fail */ +#define LDD_RNG_LONG_RUN_TEST_ERROR 0x80000000U /*!< Long run test fail */ + +#define LDD_RNG_ON_SEED_GENERATION_DONE 0x01U /*!< OnSeedGenerationDone event mask */ +#define LDD_RNG_ON_SELF_TEST_DONE 0x02U /*!< OnSelfTestDone event mask */ +#define LDD_RNG_ON_ERROR_LFSR 0x04U /*!< OnErrorLFSR event mask */ +#define LDD_RNG_ON_OSC_ERROR 0x08U /*!< OnOscError event mask */ +#define LDD_RNG_ON_SELF_TEST_ERROR 0x10U /*!< OnSelfTestError event mask */ +#define LDD_RNG_ON_STATISTICAL_ERROR 0x20U /*!< OnStatisticalError event mask */ +#define LDD_RNG_ON_FIFO_UNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ +#define LDD_RNG_ON_FIFOUNDER_FLOW_ERROR 0x40U /*!< OnFIFOUnderFlowError event mask */ + +#define LDD_RNG_STATUS_ERROR 0xFFFFU /*!< Error in RNG module flag */ +#define LDD_RNG_STATUS_NEW_SEED_DONE 0x40U /*!< New seed done flag */ +#define LDD_RNG_STATUS_SEED_DONE 0x20U /*!< Seed done flag */ +#define LDD_RNG_STATUS_SELF_TEST_DONE 0x10U /*!< Self test done flag */ +#define LDD_RNG_STATUS_RESEED_NEEDED 0x08U /*!< Reseed needed flag */ +#define LDD_RNG_STATUS_SLEEP 0x04U /*!< RNG in sleep mode */ +#define LDD_RNG_STATUS_BUSY 0x02U /*!< RNG busy flag */ + + +/* +** =================================================================== +** RNGA device types and constants +** =================================================================== +*/ + +#define LDD_RNG_ON_ERROR 0x01U /*!< OnError event mask */ + +#define LDD_RNG_STATUS_SECURITY_VIOLATION 0x01U /*!< Security violation occured */ +#define LDD_RNG_STATUS_LAST_READ_UNDERFLOW 0x02U /*!< Last read from RNGA caused underflow error */ +#define LDD_RNG_STATUS_OUT_REG_UNDERFLOW 0x04U /*!< The RNGA Output Register has been read while empty since last read of the RNGA Status Register. */ +#define LDD_RNG_STATUS_ERR_INT_PENDING 0x08U /*!< Error interrupt pending */ +#define LDD_RNG_STATUS_SLEEP_MODE 0x10U /*!< Sleep mode enabled */ + +/*! RNGA sleep mode */ +typedef enum { + LDD_RNG_SLEEP_ENABLED, /*!< RNGA is in sleep mode */ + LDD_RNG_SLEEP_DISABLED /*!< RNGA is running */ +} LDD_RNG_TSleepMode; + +/* +** =================================================================== +** DryIce device types and constants +** =================================================================== +*/ + +#define LDD_DRY_ON_TAMPER_DETECTED 0x01U /*!< OnTamperDetected event mask */ + +/* Tamper flags */ +#define LDD_DRY_TIME_OVERFLOW 0x04U /*!< RTC time overflow has occurred. */ +#define LDD_DRY_MONOTONIC_OVERFLOW 0x08U /*!< RTC monotonic overflow has occurred. */ +#define LDD_DRY_VOLTAGE_TAMPER 0x10U /*!< VBAT voltage is outside of the valid range. */ +#define LDD_DRY_CLOCK_TAMPER 0x20U /*!< The 32.768 kHz clock source is outside the valid range. */ +#define LDD_DRY_TEMPERATURE_TAMPER 0x40U /*!< The junction temperature is outside of specification. */ +#define LDD_DRY_SECURITY_TAMPER 0x80U /*!< The (optional) security module asserted its tamper detect. */ +#define LDD_DRY_FLASH_SECURITY 0x0100U /*!< The flash security is disabled. */ +#define LDD_DRY_TEST_MODE 0x0200U /*!< Any test mode has been entered. */ +/* Tamper flags indicating that the pin does not equal its expected value and was not filtered by the glitch filter (if enabled). */ +#define LDD_DRY_TAMPER_PIN_0 0x00010000U /*!< Mismatch on tamper pin 0. */ +#define LDD_DRY_TAMPER_PIN_1 0x00020000U /*!< Mismatch on tamper pin 1. */ +#define LDD_DRY_TAMPER_PIN_2 0x00040000U /*!< Mismatch on tamper pin 2. */ +#define LDD_DRY_TAMPER_PIN_3 0x00080000U /*!< Mismatch on tamper pin 3. */ +#define LDD_DRY_TAMPER_PIN_4 0x00100000U /*!< Mismatch on tamper pin 4. */ +#define LDD_DRY_TAMPER_PIN_5 0x00200000U /*!< Mismatch on tamper pin 5. */ +#define LDD_DRY_TAMPER_PIN_6 0x00400000U /*!< Mismatch on tamper pin 6. */ +#define LDD_DRY_TAMPER_PIN_7 0x00800000U /*!< Mismatch on tamper pin 7. */ + +#define LDD_DRY_SECURE_KEY_WORD_0 0x01U /*!< Secure key word 0 mask */ +#define LDD_DRY_SECURE_KEY_WORD_1 0x02U /*!< Secure key word 1 mask */ +#define LDD_DRY_SECURE_KEY_WORD_2 0x04U /*!< Secure key word 2 mask */ +#define LDD_DRY_SECURE_KEY_WORD_3 0x08U /*!< Secure key word 3 mask */ +#define LDD_DRY_SECURE_KEY_WORD_4 0x10U /*!< Secure key word 4 mask */ +#define LDD_DRY_SECURE_KEY_WORD_5 0x20U /*!< Secure key word 5 mask */ +#define LDD_DRY_SECURE_KEY_WORD_6 0x40U /*!< Secure key word 6 mask */ +#define LDD_DRY_SECURE_KEY_WORD_7 0x80U /*!< Secure key word 7 mask */ + +/* +** =================================================================== +** NFC device types and constants +** =================================================================== +*/ + +/* Events' masks */ +#define LDD_NFC_ON_CMD_ERROR 0x01U /*!< OnCmdError event mask */ +#define LDD_NFC_ON_CMD_DONE 0x02U /*!< OnCmdDone event mask */ + +/* Pins' masks */ +#define LDD_NFC_CE0_PIN 0x01U /*!< CE0 pin mask */ +#define LDD_NFC_RB0_PIN 0x02U /*!< RB0 pin mask */ +#define LDD_NFC_CE1_PIN 0x04U /*!< CE1 pin mask */ +#define LDD_NFC_RB1_PIN 0x08U /*!< RB1 pin mask */ +#define LDD_NFC_CE2_PIN 0x10U /*!< CE2 pin mask */ +#define LDD_NFC_RB2_PIN 0x20U /*!< RB2 pin mask */ +#define LDD_NFC_CE3_PIN 0x40U /*!< CE3 pin mask */ +#define LDD_NFC_RB3_PIN 0x80U /*!< RB3 pin mask */ +#define LDD_NFC_ALE_PIN 0x0100U /*!< ALE pin mask */ +#define LDD_NFC_CLE_PIN 0x0200U /*!< CLE pin mask */ +#define LDD_NFC_RE_PIN 0x0400U /*!< RE pin mask */ +#define LDD_NFC_WE_PIN 0x0800U /*!< WE pin mask */ +#define LDD_NFC_D0_PIN 0x00010000U /*!< D0 pin mask */ +#define LDD_NFC_D1_PIN 0x00020000U /*!< D1 pin mask */ +#define LDD_NFC_D2_PIN 0x00040000U /*!< D2 pin mask */ +#define LDD_NFC_D3_PIN 0x00080000U /*!< D3 pin mask */ +#define LDD_NFC_D4_PIN 0x00100000U /*!< D4 pin mask */ +#define LDD_NFC_D5_PIN 0x00200000U /*!< D5 pin mask */ +#define LDD_NFC_D6_PIN 0x00400000U /*!< D6 pin mask */ +#define LDD_NFC_D7_PIN 0x00800000U /*!< D7 pin mask */ +#define LDD_NFC_D8_PIN 0x01000000U /*!< D8 pin mask */ +#define LDD_NFC_D9_PIN 0x02000000U /*!< D9 pin mask */ +#define LDD_NFC_D10_PIN 0x04000000U /*!< D10 pin mask */ +#define LDD_NFC_D11_PIN 0x08000000U /*!< D11 pin mask */ +#define LDD_NFC_D12_PIN 0x10000000U /*!< D12 pin mask */ +#define LDD_NFC_D13_PIN 0x20000000U /*!< D13 pin mask */ +#define LDD_NFC_D14_PIN 0x40000000U /*!< D14 pin mask */ +#define LDD_NFC_D15_PIN 0x80000000U /*!< D15 pin mask */ + +typedef uint32_t LDD_NFC_TTargetID; /*!< NFC target ID type */ + +/*! NCF command codes */ +typedef enum { + LDD_NFC_CMD_NONE = 0x00U, /* No command */ + LDD_NFC_CMD_RESET = 0x01U, /* Reset command */ + LDD_NFC_CMD_ERASE = 0x02U, /* Erase command */ + LDD_NFC_CMD_READ_ID = 0x03U, /* Read ID command */ + LDD_NFC_CMD_READ_PAGES = 0x04U, /* Read pages command */ + LDD_NFC_CMD_WRITE_PAGES = 0x05U, /* Write pages command */ + LDD_NFC_CMD_ERASE_BLOCKS = 0x06U, /* Erase page command */ + LDD_NFC_CMD_READ_RAW_PAGE = 0x07U, /* Read raw page command */ + LDD_NFC_CMD_WRITE_RAW_PAGE = 0x08U /* Write raw page command */ +} LDD_NFC_TeCmd; + +/* +** =================================================================== +** LCDC device types and constants +** =================================================================== +*/ + +#define LDD_LCDC_ON_ERROR 0x01U /*!< OnError event mask */ +#define LDD_LCDC_ON_START_OF_FRAME 0x02U /*!< OnStartOfFrame event mask */ +#define LDD_LCDC_ON_END_OF_FRAME 0x04U /*!< OnEndOfFrame event mask */ + +#define LDD_LCDC_NO_ERR 0x00U /*!< No error */ +#define LDD_LCDC_PLANE_0_UNDERRUN_ERR 0x01U /*!< Plane 0 underrurn error */ +#define LDD_LCDC_PLANE_1_UNDERRUN_ERR 0x02U /*!< Plane 1 underrurn error */ + +#define LDD_LCDC_REVERSED_VERTICAL_SCAN 0x8000U /*!< Enable reversed vertical scan (flip along x-axis) */ + +/*! Bitmap description */ +typedef struct { + LDD_TData *Address; /*!< Bitmap starting address */ + uint16_t Width; /*!< Bitmap width */ + uint16_t Height; /*!< Bitmap height */ + uint16_t Format; /*!< Bitmap format */ +} LDD_LCDC_TBitmap; + +/*! Window description */ +typedef struct { + uint16_t X; /*!< Window position in bitmap - X */ + uint16_t Y; /*!< Window position in bitmap - Y */ + uint16_t Width; /*!< Window width */ + uint16_t Height; /*!< Window height */ +} LDD_LCDC_TWindow; + +/*! Cursor type */ +typedef enum { + LDD_LCDC_DISABLED = 0, /*!< Cursor disabled */ + LDD_LCDC_ALWAYS_1, /*!< Cursor 1''s, monochrome display only. */ + LDD_LCDC_ALWAYS_0, /*!< Cursor 0''s, monochrome display only. */ + LDD_LCDC_COLOR, /*!< Defined cursor color, color display only. */ + LDD_LCDC_INVERTED, /*!< Inverted background, monochrome display only. */ + LDD_LCDC_INVERTED_COLOR, /*!< Inverted cursor color, color display only. */ + LDD_LCDC_AND, /*!< Cursor color AND backgroun, color display only. */ + LDD_LCDC_OR, /*!< Cursor color OR backgroun, color display only. */ + LDD_LCDC_XOR +} LDD_LCDC_CursorOperation; + +/*! Plane identification */ +typedef enum { + LDD_LCDC_PLANE_COMMON, /*!< Common for all planes */ + LDD_LCDC_PLANE_0, /*!< Plane (layer) 0 */ + LDD_LCDC_PLANE_1 /*!< Plane (layer) 1 */ +} LDD_LCDC_TPlaneID; + + +/* +** =================================================================== +** Interrupt vector constants +** =================================================================== +*/ +#define LDD_ivIndex_INT_Initial_Stack_Pointer 0x00u +#define LDD_ivIndex_INT_Initial_Program_Counter 0x01u +#define LDD_ivIndex_INT_NMI 0x02u +#define LDD_ivIndex_INT_Hard_Fault 0x03u +#define LDD_ivIndex_INT_Mem_Manage_Fault 0x04u +#define LDD_ivIndex_INT_Bus_Fault 0x05u +#define LDD_ivIndex_INT_Usage_Fault 0x06u +#define LDD_ivIndex_INT_Reserved7 0x07u +#define LDD_ivIndex_INT_Reserved8 0x08u +#define LDD_ivIndex_INT_Reserved9 0x09u +#define LDD_ivIndex_INT_Reserved10 0x0Au +#define LDD_ivIndex_INT_SVCall 0x0Bu +#define LDD_ivIndex_INT_DebugMonitor 0x0Cu +#define LDD_ivIndex_INT_Reserved13 0x0Du +#define LDD_ivIndex_INT_PendableSrvReq 0x0Eu +#define LDD_ivIndex_INT_SysTick 0x0Fu +#define LDD_ivIndex_INT_DMA0 0x10u +#define LDD_ivIndex_INT_DMA1 0x11u +#define LDD_ivIndex_INT_DMA2 0x12u +#define LDD_ivIndex_INT_DMA3 0x13u +#define LDD_ivIndex_INT_DMA_Error 0x14u +#define LDD_ivIndex_INT_Reserved21 0x15u +#define LDD_ivIndex_INT_FTFL 0x16u +#define LDD_ivIndex_INT_Read_Collision 0x17u +#define LDD_ivIndex_INT_LVD_LVW 0x18u +#define LDD_ivIndex_INT_LLW 0x19u +#define LDD_ivIndex_INT_Watchdog 0x1Au +#define LDD_ivIndex_INT_I2C0 0x1Bu +#define LDD_ivIndex_INT_SPI0 0x1Cu +#define LDD_ivIndex_INT_I2S0_Tx 0x1Du +#define LDD_ivIndex_INT_I2S0_Rx 0x1Eu +#define LDD_ivIndex_INT_UART0_LON 0x1Fu +#define LDD_ivIndex_INT_UART0_RX_TX 0x20u +#define LDD_ivIndex_INT_UART0_ERR 0x21u +#define LDD_ivIndex_INT_UART1_RX_TX 0x22u +#define LDD_ivIndex_INT_UART1_ERR 0x23u +#define LDD_ivIndex_INT_UART2_RX_TX 0x24u +#define LDD_ivIndex_INT_UART2_ERR 0x25u +#define LDD_ivIndex_INT_ADC0 0x26u +#define LDD_ivIndex_INT_CMP0 0x27u +#define LDD_ivIndex_INT_CMP1 0x28u +#define LDD_ivIndex_INT_FTM0 0x29u +#define LDD_ivIndex_INT_FTM1 0x2Au +#define LDD_ivIndex_INT_CMT 0x2Bu +#define LDD_ivIndex_INT_RTC 0x2Cu +#define LDD_ivIndex_INT_RTC_Seconds 0x2Du +#define LDD_ivIndex_INT_PIT0 0x2Eu +#define LDD_ivIndex_INT_PIT1 0x2Fu +#define LDD_ivIndex_INT_PIT2 0x30u +#define LDD_ivIndex_INT_PIT3 0x31u +#define LDD_ivIndex_INT_PDB0 0x32u +#define LDD_ivIndex_INT_USB0 0x33u +#define LDD_ivIndex_INT_USBDCD 0x34u +#define LDD_ivIndex_INT_TSI0 0x35u +#define LDD_ivIndex_INT_MCG 0x36u +#define LDD_ivIndex_INT_LPTimer 0x37u +#define LDD_ivIndex_INT_PORTA 0x38u +#define LDD_ivIndex_INT_PORTB 0x39u +#define LDD_ivIndex_INT_PORTC 0x3Au +#define LDD_ivIndex_INT_PORTD 0x3Bu +#define LDD_ivIndex_INT_PORTE 0x3Cu +#define LDD_ivIndex_INT_SWI 0x3Du + +#endif /* __PE_Types_H */ + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.c new file mode 100644 index 0000000..6a77e28 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.c @@ -0,0 +1,185 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PWMA.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM +** Version : Component 02.241, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** Settings : +** Component name : PWMA +** PWM or PPG device : FTM0_C0V +** Duty compare : +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Same period in modes : no +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** PWM_LDD : PWM_LDD +** Contents : +** SetRatio16 - byte PWMA_SetRatio16(word Ratio); +** SetDutyUS - byte PWMA_SetDutyUS(word Time); +** SetDutyMS - byte PWMA_SetDutyMS(word Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PWMA.c +** @version 01.01 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +*/ +/*! +** @addtogroup PWMA_module PWMA module documentation +** @{ +*/ + +/* MODULE PWMA. */ + +#include "PWMA.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : PWMA_SetRatio16 (component PWM) +** Description : +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** Parameters : +** NAME - DESCRIPTION +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +/* +byte PWMA_SetRatio16(word Ratio) +** This method is implemented as a macro. See PWMA.h file. ** +*/ + +/* +** =================================================================== +** Method : PWMA_SetDutyUS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in microseconds] +** (0 to --- us in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +/* +byte PWMA_SetDutyUS(word Time) +** This method is implemented as a macro. See PWMA.h file. ** +*/ + +/* +** =================================================================== +** Method : PWMA_SetDutyMS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in milliseconds] +** (0 to --- ms in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +/* +byte PWMA_SetDutyMS(word Time) +** This method is implemented as a macro. See PWMA.h file. ** +*/ + +/* END PWMA. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.h new file mode 100644 index 0000000..0a9278a --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMA.h @@ -0,0 +1,194 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PWMA.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM +** Version : Component 02.241, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** Settings : +** Component name : PWMA +** PWM or PPG device : FTM0_C0V +** Duty compare : +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Same period in modes : no +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** PWM_LDD : PWM_LDD +** Contents : +** SetRatio16 - byte PWMA_SetRatio16(word Ratio); +** SetDutyUS - byte PWMA_SetDutyUS(word Time); +** SetDutyMS - byte PWMA_SetDutyMS(word Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PWMA.h +** @version 01.01 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +*/ +/*! +** @addtogroup PWMA_module PWMA module documentation +** @{ +*/ + +#ifndef __PWMA_H +#define __PWMA_H + +/* MODULE PWMA. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "PwmLdd1.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PWMA_PERIOD_VALUE PwmLdd1_PERIOD_VALUE /* Initial period value in ticks of the timer. It is available only if the bean is enabled in high speed mode. */ +#define PWMA_PERIOD_VALUE_HIGH PwmLdd1_PERIOD_VALUE_0 /* Period value in ticks of the timer in high speed mode. It is available only if the bean is enabled in high speed mode. */ + + +/* +** =================================================================== +** Method : PWMA_SetRatio16 (component PWM) +** Description : +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** Parameters : +** NAME - DESCRIPTION +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +#define PWMA_SetRatio16(Ratio) (PwmLdd1_SetRatio16(PwmLdd1_DeviceData, Ratio)) + +/* +** =================================================================== +** Method : PWMA_SetDutyUS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in microseconds] +** (0 to --- us in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +#define PWMA_SetDutyUS(Time) (PwmLdd1_SetDutyUS(PwmLdd1_DeviceData, Time)) + +/* +** =================================================================== +** Method : PWMA_SetDutyMS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in milliseconds] +** (0 to --- ms in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +#define PWMA_SetDutyMS(Time) (PwmLdd1_SetDutyMS(PwmLdd1_DeviceData, Time)) + +/* END PWMA. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __PWMA_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.c new file mode 100644 index 0000000..bd032b5 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.c @@ -0,0 +1,185 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PWMB.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM +** Version : Component 02.241, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** Settings : +** Component name : PWMB +** PWM or PPG device : FTM0_C2V +** Duty compare : +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Same period in modes : no +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** PWM_LDD : PWM_LDD +** Contents : +** SetRatio16 - byte PWMB_SetRatio16(word Ratio); +** SetDutyUS - byte PWMB_SetDutyUS(word Time); +** SetDutyMS - byte PWMB_SetDutyMS(word Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PWMB.c +** @version 01.01 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +*/ +/*! +** @addtogroup PWMB_module PWMB module documentation +** @{ +*/ + +/* MODULE PWMB. */ + +#include "PWMB.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : PWMB_SetRatio16 (component PWM) +** Description : +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** Parameters : +** NAME - DESCRIPTION +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +/* +byte PWMB_SetRatio16(word Ratio) +** This method is implemented as a macro. See PWMB.h file. ** +*/ + +/* +** =================================================================== +** Method : PWMB_SetDutyUS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in microseconds] +** (0 to --- us in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +/* +byte PWMB_SetDutyUS(word Time) +** This method is implemented as a macro. See PWMB.h file. ** +*/ + +/* +** =================================================================== +** Method : PWMB_SetDutyMS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in milliseconds] +** (0 to --- ms in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +/* +byte PWMB_SetDutyMS(word Time) +** This method is implemented as a macro. See PWMB.h file. ** +*/ + +/* END PWMB. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.h new file mode 100644 index 0000000..1da59b3 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PWMB.h @@ -0,0 +1,194 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PWMB.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM +** Version : Component 02.241, Driver 01.01, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** Settings : +** Component name : PWMB +** PWM or PPG device : FTM0_C2V +** Duty compare : +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Same period in modes : no +** Component uses entire timer : no +** Initialization : +** Enabled in init. code : yes +** Events enabled in init. : yes +** CPU clock/speed selection : +** High speed mode : This component enabled +** Low speed mode : This component disabled +** Slow speed mode : This component disabled +** Referenced components : +** PWM_LDD : PWM_LDD +** Contents : +** SetRatio16 - byte PWMB_SetRatio16(word Ratio); +** SetDutyUS - byte PWMB_SetDutyUS(word Time); +** SetDutyMS - byte PWMB_SetDutyMS(word Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PWMB.h +** @version 01.01 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +*/ +/*! +** @addtogroup PWMB_module PWMB module documentation +** @{ +*/ + +#ifndef __PWMB_H +#define __PWMB_H + +/* MODULE PWMB. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "PwmLdd2.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PWMB_PERIOD_VALUE PwmLdd2_PERIOD_VALUE /* Initial period value in ticks of the timer. It is available only if the bean is enabled in high speed mode. */ +#define PWMB_PERIOD_VALUE_HIGH PwmLdd2_PERIOD_VALUE_0 /* Period value in ticks of the timer in high speed mode. It is available only if the bean is enabled in high speed mode. */ + + +/* +** =================================================================== +** Method : PWMB_SetRatio16 (component PWM) +** Description : +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** Parameters : +** NAME - DESCRIPTION +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** =================================================================== +*/ +#define PWMB_SetRatio16(Ratio) (PwmLdd2_SetRatio16(PwmLdd2_DeviceData, Ratio)) + +/* +** =================================================================== +** Method : PWMB_SetDutyUS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in microseconds] +** (0 to --- us in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +#define PWMB_SetDutyUS(Time) (PwmLdd2_SetDutyUS(PwmLdd2_DeviceData, Time)) + +/* +** =================================================================== +** Method : PWMB_SetDutyMS (component PWM) +** Description : +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit +** unsigned integer number. +** Parameters : +** NAME - DESCRIPTION +** Time - Duty to set [in milliseconds] +** (0 to --- ms in high speed mode) +** Returns : +** --- - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - This device does not work in +** the active speed mode +** ERR_MATH - Overflow during evaluation +** ERR_RANGE - Parameter out of range +** =================================================================== +*/ +#define PWMB_SetDutyMS(Time) (PwmLdd2_SetDutyMS(PwmLdd2_DeviceData, Time)) + +/* END PWMB. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __PWMB_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.c new file mode 100644 index 0000000..ea2cda4 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.c @@ -0,0 +1,334 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PwmLdd1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM_LDD +** Version : Component 01.014, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : PwmLdd1 +** Period device : FTM0_MOD +** Duty device : FTM0_C0V +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Initialization : +** Enabled in init. code : yes +** Auto initialization : yes +** Event mask : +** OnEnd : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked component : TU1 +** Contents : +** Init - LDD_TDeviceData* PwmLdd1_Init(LDD_TUserData *UserDataPtr); +** SetRatio16 - LDD_TError PwmLdd1_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); +** SetDutyUS - LDD_TError PwmLdd1_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** SetDutyMS - LDD_TError PwmLdd1_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PwmLdd1.c +** @version 01.03 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup PwmLdd1_module PwmLdd1 module documentation +** @{ +*/ + +/* MODULE PwmLdd1. */ + +#include "PwmLdd1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TDeviceData *LinkedDeviceDataPtr; + bool EnUser; /* Enable/Disable device */ + uint16_t RatioStore; /* Ratio of L-level to H-level */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} PwmLdd1_TDeviceData; + +typedef PwmLdd1_TDeviceData *PwmLdd1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static PwmLdd1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; + +#define CHANNEL 0x00U +/* Internal method prototypes */ +static void SetRatio(LDD_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : PwmLdd1_Init (component PWM_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* PwmLdd1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + PwmLdd1_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->EnUser = TRUE; /* Set the flag "device enabled" */ + DeviceDataPrv->RatioStore = 0x01U; /* Ratio after initialization */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_PwmLdd1_ID,DeviceDataPrv); + DeviceDataPrv->LinkedDeviceDataPtr = TU1_Init((LDD_TUserData *)NULL); + if (DeviceDataPrv->LinkedDeviceDataPtr == NULL) { /* Is initialization of TimerUnit unsuccessful? */ + /* Unregistration of the device structure */ + PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_PwmLdd1_ID); + /* Deallocation of the device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: Dynamic allocation is simulated, no deallocation code is generated */ + return NULL; /* If so, then the PWM initialization is also unsuccessful */ + } + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : PwmLdd1_SetRatio16 (component PWM_LDD) +*/ +/*! +** @brief +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** [Starting pulse width] property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio) +{ + PwmLdd1_TDeviceData *DeviceDataPrv = (PwmLdd1_TDeviceData *)DeviceDataPtr; + + DeviceDataPrv->RatioStore = Ratio; /* Store new value of the ratio */ + SetRatio(DeviceDataPtr); + return ERR_OK; +} + +/* +** =================================================================== +** Method : PwmLdd1_SetDutyUS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in microseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time) +{ + PwmLdd1_TDeviceData *DeviceDataPrv = (PwmLdd1_TDeviceData *)DeviceDataPtr; + LDD_TimerUnit_Tfloat rtval; /* Result of multiplication */ + + /* Time test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (Time > 0x03E8U) { /* Is the given value out of range? */ + return ERR_PARAM_RANGE; /* If yes then error */ + } + rtval = Time * 65.536F; /* Multiply given value and actual clock configuration coefficient */ + if (rtval > 0xFFFFUL) { /* Is the result greater than 65535 ? */ + DeviceDataPrv->RatioStore = 0xFFFFU; /* If yes then use maximal possible value */ + } + else { + DeviceDataPrv->RatioStore = (uint16_t)rtval; + } + SetRatio(DeviceDataPtr); /* Calculate and set up new appropriate values of the duty register */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : PwmLdd1_SetDutyMS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in milliseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time) +{ + PwmLdd1_TDeviceData *DeviceDataPrv = (PwmLdd1_TDeviceData *)DeviceDataPtr; + LDD_TimerUnit_Tfloat rtval; /* Result of multiplication */ + + /* Time test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (Time > 0x01U) { /* Is the given value out of range? */ + return ERR_PARAM_RANGE; /* If yes then error */ + } + rtval = Time * 65536.0F; /* Multiply given value and actual clock configuration coefficient */ + if (rtval > 0xFFFFUL) { /* Is the result greater than 65535 ? */ + DeviceDataPrv->RatioStore = 0xFFFFU; /* If yes then use maximal possible value */ + } + else { + DeviceDataPrv->RatioStore = (uint16_t)rtval; + } + SetRatio(DeviceDataPtr); /* Calculate and set up new appropriate values of the duty register */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : SetRatio (component PWM_LDD) +** +** Description : +** This method calculates new value of duty compare register from +** variable RatioStore. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SetRatio(LDD_TDeviceData *DeviceDataPtr) +{ + PwmLdd1_TDeviceData *DeviceDataPrv = (PwmLdd1_TDeviceData*)DeviceDataPtr; + uint16_t Period; + uint16_t Duty; + + (void)TU1_GetPeriodTicks(DeviceDataPrv->LinkedDeviceDataPtr, &Period); + if (Period == 0U) { + Duty = DeviceDataPrv->RatioStore; + } + else { + Duty = (uint16_t)((((uint32_t)(Period) * DeviceDataPrv->RatioStore) + 0x8000) >> 0x10); + } + (void)TU1_SetOffsetTicks(DeviceDataPrv->LinkedDeviceDataPtr, CHANNEL, Duty); +} +/* END PwmLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.h new file mode 100644 index 0000000..2a9b54d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd1.h @@ -0,0 +1,262 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PwmLdd1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM_LDD +** Version : Component 01.014, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : PwmLdd1 +** Period device : FTM0_MOD +** Duty device : FTM0_C0V +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Initialization : +** Enabled in init. code : yes +** Auto initialization : yes +** Event mask : +** OnEnd : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked component : TU1 +** Contents : +** Init - LDD_TDeviceData* PwmLdd1_Init(LDD_TUserData *UserDataPtr); +** SetRatio16 - LDD_TError PwmLdd1_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); +** SetDutyUS - LDD_TError PwmLdd1_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** SetDutyMS - LDD_TError PwmLdd1_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PwmLdd1.h +** @version 01.03 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup PwmLdd1_module PwmLdd1 module documentation +** @{ +*/ + +#ifndef __PwmLdd1_H +#define __PwmLdd1_H + +/* MODULE PwmLdd1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "TU1.h" +#include "FTM_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PwmLdd1_PERIOD_VALUE 0x61A8UL /* Initial period value in ticks of the timer. */ +#define PwmLdd1_PERIOD_VALUE_0 0x61A8UL /* Period value in ticks of the timer in clock configuration 0. */ + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define PwmLdd1_PRPH_BASE_ADDRESS 0x40038000U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define PwmLdd1_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_PwmLdd1_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define PwmLdd1_Init_METHOD_ENABLED /*!< Init method of the component PwmLdd1 is enabled (generated) */ +#define PwmLdd1_SetRatio16_METHOD_ENABLED /*!< SetRatio16 method of the component PwmLdd1 is enabled (generated) */ +#define PwmLdd1_SetDutyUS_METHOD_ENABLED /*!< SetDutyUS method of the component PwmLdd1 is enabled (generated) */ +#define PwmLdd1_SetDutyMS_METHOD_ENABLED /*!< SetDutyMS method of the component PwmLdd1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ + + + +/* +** =================================================================== +** Method : PwmLdd1_Init (component PWM_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* PwmLdd1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : PwmLdd1_SetRatio16 (component PWM_LDD) +*/ +/*! +** @brief +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** [Starting pulse width] property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); + +/* +** =================================================================== +** Method : PwmLdd1_SetDutyUS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in microseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); + +/* +** =================================================================== +** Method : PwmLdd1_SetDutyMS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in milliseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd1_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); + +/* END PwmLdd1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __PwmLdd1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.c new file mode 100644 index 0000000..4f772cc --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.c @@ -0,0 +1,334 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PwmLdd2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM_LDD +** Version : Component 01.014, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : PwmLdd2 +** Period device : FTM0_MOD +** Duty device : FTM0_C2V +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Initialization : +** Enabled in init. code : yes +** Auto initialization : yes +** Event mask : +** OnEnd : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked component : TU1 +** Contents : +** Init - LDD_TDeviceData* PwmLdd2_Init(LDD_TUserData *UserDataPtr); +** SetRatio16 - LDD_TError PwmLdd2_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); +** SetDutyUS - LDD_TError PwmLdd2_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** SetDutyMS - LDD_TError PwmLdd2_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PwmLdd2.c +** @version 01.03 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup PwmLdd2_module PwmLdd2 module documentation +** @{ +*/ + +/* MODULE PwmLdd2. */ + +#include "PwmLdd2.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + LDD_TDeviceData *LinkedDeviceDataPtr; + bool EnUser; /* Enable/Disable device */ + uint16_t RatioStore; /* Ratio of L-level to H-level */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} PwmLdd2_TDeviceData; + +typedef PwmLdd2_TDeviceData *PwmLdd2_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static PwmLdd2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; + +#define CHANNEL 0x01U +/* Internal method prototypes */ +static void SetRatio(LDD_TDeviceData *DeviceDataPtr); +/* +** =================================================================== +** Method : PwmLdd2_Init (component PWM_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* PwmLdd2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + PwmLdd2_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->EnUser = TRUE; /* Set the flag "device enabled" */ + DeviceDataPrv->RatioStore = 0x01U; /* Ratio after initialization */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_PwmLdd2_ID,DeviceDataPrv); + DeviceDataPrv->LinkedDeviceDataPtr = TU1_Init((LDD_TUserData *)NULL); + if (DeviceDataPrv->LinkedDeviceDataPtr == NULL) { /* Is initialization of TimerUnit unsuccessful? */ + /* Unregistration of the device structure */ + PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_PwmLdd2_ID); + /* Deallocation of the device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: Dynamic allocation is simulated, no deallocation code is generated */ + return NULL; /* If so, then the PWM initialization is also unsuccessful */ + } + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : PwmLdd2_SetRatio16 (component PWM_LDD) +*/ +/*! +** @brief +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** [Starting pulse width] property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio) +{ + PwmLdd2_TDeviceData *DeviceDataPrv = (PwmLdd2_TDeviceData *)DeviceDataPtr; + + DeviceDataPrv->RatioStore = Ratio; /* Store new value of the ratio */ + SetRatio(DeviceDataPtr); + return ERR_OK; +} + +/* +** =================================================================== +** Method : PwmLdd2_SetDutyUS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in microseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time) +{ + PwmLdd2_TDeviceData *DeviceDataPrv = (PwmLdd2_TDeviceData *)DeviceDataPtr; + LDD_TimerUnit_Tfloat rtval; /* Result of multiplication */ + + /* Time test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (Time > 0x03E8U) { /* Is the given value out of range? */ + return ERR_PARAM_RANGE; /* If yes then error */ + } + rtval = Time * 65.536F; /* Multiply given value and actual clock configuration coefficient */ + if (rtval > 0xFFFFUL) { /* Is the result greater than 65535 ? */ + DeviceDataPrv->RatioStore = 0xFFFFU; /* If yes then use maximal possible value */ + } + else { + DeviceDataPrv->RatioStore = (uint16_t)rtval; + } + SetRatio(DeviceDataPtr); /* Calculate and set up new appropriate values of the duty register */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : PwmLdd2_SetDutyMS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in milliseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time) +{ + PwmLdd2_TDeviceData *DeviceDataPrv = (PwmLdd2_TDeviceData *)DeviceDataPtr; + LDD_TimerUnit_Tfloat rtval; /* Result of multiplication */ + + /* Time test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (Time > 0x01U) { /* Is the given value out of range? */ + return ERR_PARAM_RANGE; /* If yes then error */ + } + rtval = Time * 65536.0F; /* Multiply given value and actual clock configuration coefficient */ + if (rtval > 0xFFFFUL) { /* Is the result greater than 65535 ? */ + DeviceDataPrv->RatioStore = 0xFFFFU; /* If yes then use maximal possible value */ + } + else { + DeviceDataPrv->RatioStore = (uint16_t)rtval; + } + SetRatio(DeviceDataPtr); /* Calculate and set up new appropriate values of the duty register */ + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : SetRatio (component PWM_LDD) +** +** Description : +** This method calculates new value of duty compare register from +** variable RatioStore. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void SetRatio(LDD_TDeviceData *DeviceDataPtr) +{ + PwmLdd2_TDeviceData *DeviceDataPrv = (PwmLdd2_TDeviceData*)DeviceDataPtr; + uint16_t Period; + uint16_t Duty; + + (void)TU1_GetPeriodTicks(DeviceDataPrv->LinkedDeviceDataPtr, &Period); + if (Period == 0U) { + Duty = DeviceDataPrv->RatioStore; + } + else { + Duty = (uint16_t)((((uint32_t)(Period) * DeviceDataPrv->RatioStore) + 0x8000) >> 0x10); + } + (void)TU1_SetOffsetTicks(DeviceDataPrv->LinkedDeviceDataPtr, CHANNEL, Duty); +} +/* END PwmLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.h new file mode 100644 index 0000000..aedeb0b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/PwmLdd2.h @@ -0,0 +1,262 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : PwmLdd2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : PWM_LDD +** Version : Component 01.014, Driver 01.03, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +** Settings : +** Component name : PwmLdd2 +** Period device : FTM0_MOD +** Duty device : FTM0_C2V +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Counter : FTM0_CNT +** Interrupt service/event : Disabled +** Period : 1 kHz +** Starting pulse width : 0 ms +** Initial polarity : high +** Initialization : +** Enabled in init. code : yes +** Auto initialization : yes +** Event mask : +** OnEnd : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Referenced components : +** Linked component : TU1 +** Contents : +** Init - LDD_TDeviceData* PwmLdd2_Init(LDD_TUserData *UserDataPtr); +** SetRatio16 - LDD_TError PwmLdd2_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); +** SetDutyUS - LDD_TError PwmLdd2_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** SetDutyMS - LDD_TError PwmLdd2_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file PwmLdd2.h +** @version 01.03 +** @brief +** This component implements a pulse-width modulation generator +** that generates signal with variable duty and fixed cycle. +** This PWM component provides a high level API for unified +** hardware access to various timer devices using the TimerUnit +** component. +*/ +/*! +** @addtogroup PwmLdd2_module PwmLdd2 module documentation +** @{ +*/ + +#ifndef __PwmLdd2_H +#define __PwmLdd2_H + +/* MODULE PwmLdd2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "TU1.h" +#include "FTM_PDD.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PwmLdd2_PERIOD_VALUE 0x61A8UL /* Initial period value in ticks of the timer. */ +#define PwmLdd2_PERIOD_VALUE_0 0x61A8UL /* Period value in ticks of the timer in clock configuration 0. */ + +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define PwmLdd2_PRPH_BASE_ADDRESS 0x40038000U + +/*! Device data structure pointer used when auto initialization property is enabled. This constant can be passed as a first parameter to all component's methods. */ +#define PwmLdd2_DeviceData ((LDD_TDeviceData *)PE_LDD_GetDeviceStructure(PE_LDD_COMPONENT_PwmLdd2_ID)) + +/* Methods configuration constants - generated for all enabled component's methods */ +#define PwmLdd2_Init_METHOD_ENABLED /*!< Init method of the component PwmLdd2 is enabled (generated) */ +#define PwmLdd2_SetRatio16_METHOD_ENABLED /*!< SetRatio16 method of the component PwmLdd2 is enabled (generated) */ +#define PwmLdd2_SetDutyUS_METHOD_ENABLED /*!< SetDutyUS method of the component PwmLdd2 is enabled (generated) */ +#define PwmLdd2_SetDutyMS_METHOD_ENABLED /*!< SetDutyMS method of the component PwmLdd2 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ + + + +/* +** =================================================================== +** Method : PwmLdd2_Init (component PWM_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* PwmLdd2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : PwmLdd2_SetRatio16 (component PWM_LDD) +*/ +/*! +** @brief +** This method sets a new duty-cycle ratio. Ratio is expressed +** as a 16-bit unsigned integer number. 0 - FFFF value is +** proportional to ratio 0 - 100%. The method is available +** only if it is not selected list of predefined values in +** [Starting pulse width] property. +** Note: Calculated duty depends on the timer possibilities and +** on the selected period. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Ratio - Ratio to set. 0 - 65535 value is +** proportional to ratio 0 - 100% +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetRatio16(LDD_TDeviceData *DeviceDataPtr, uint16_t Ratio); + +/* +** =================================================================== +** Method : PwmLdd2_SetDutyUS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in microseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in microseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetDutyUS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); + +/* +** =================================================================== +** Method : PwmLdd2_SetDutyMS (component PWM_LDD) +*/ +/*! +** @brief +** This method sets the new duty value of the output signal. +** The duty is expressed in milliseconds as a 16-bit unsigned +** integer number. The method is available only if it is not +** selected list of predefined values in [Starting pulse width] +** property. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** Time - Duty to set [in milliseconds] +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +** ERR_MATH - Overflow during evaluation +** ERR_PARAM_RANGE - Parameter out of range +*/ +/* ===================================================================*/ +LDD_TError PwmLdd2_SetDutyMS(LDD_TDeviceData *DeviceDataPtr, uint16_t Time); + +/* END PwmLdd2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __PwmLdd2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.c new file mode 100644 index 0000000..c759bc8 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.c @@ -0,0 +1,297 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTOSCNTRLDD1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 08:06, # CodeGen: 1 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : RTOSCNTRLDD1 +** Module name : PIT +** Counter : PIT_CVAL0 +** Counter direction : Down +** Counter width : 32 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 25 MHz +** Counter restart : On-match +** Period device : PIT_LDVAL0 +** Period : 0.1 ms +** Interrupt : Enabled +** Interrupt : INT_PIT0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file RTOSCNTRLDD1.c +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup RTOSCNTRLDD1_module RTOSCNTRLDD1 module documentation +** @{ +*/ + +/* MODULE RTOSCNTRLDD1. */ + +#include "FRTOS1.h" +#include "RTOSCNTRLDD1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} RTOSCNTRLDD1_TDeviceData; + +typedef RTOSCNTRLDD1_TDeviceData *RTOSCNTRLDD1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static RTOSCNTRLDD1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; +/* {FreeRTOS RTOS Adapter} Global variable used for passing a parameter into ISR */ +static RTOSCNTRLDD1_TDeviceDataPtr INT_PIT0__BAREBOARD_RTOS_ISRPARAM; + +#define AVAILABLE_EVENTS_MASK (LDD_TEventMask)(LDD_TIMERUNIT_ON_COUNTER_RESTART) + +/* Internal method prototypes */ +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + RTOSCNTRLDD1_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* Interrupt vector(s) allocation */ + /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ + INT_PIT0__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; + /* SIM_SCGC6: PIT=1 */ + SIM_SCGC6 |= SIM_SCGC6_PIT_MASK; + /* PIT_MCR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MDIS=0,FRZ=0 */ + PIT_MCR = 0x00U; /* Enable device clock */ + /* PIT_TCTRL0: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TIE=0,TEN=0 */ + PIT_TCTRL0 = 0x00U; /* Clear control register */ + /* PIT_TFLG0: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TIF=1 */ + PIT_TFLG0 = PIT_TFLG_TIF_MASK; /* Clear timer flag register */ + /* PIT_LDVAL0: TSV=0x09C3 */ + PIT_LDVAL0 = PIT_LDVAL_TSV(0x09C3); /* Set up load register */ + /* NVICIP30: PRI30=0x80 */ + NVICIP30 = NVIC_IP_PRI30(0x80); + /* NVICISER0: SETENA|=0x40000000 */ + NVICISER0 |= NVIC_ISER_SETENA(0x40000000); + /* PIT_TCTRL0: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TIE=1,TEN=1 */ + PIT_TCTRL0 = (PIT_TCTRL_TIE_MASK | PIT_TCTRL_TEN_MASK); /* Set up control register */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_RTOSCNTRLDD1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Deinit (component TimerUnit_LDD) +*/ +/*! +** @brief +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupts vectors, etc. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by Init method +*/ +/* ===================================================================*/ +void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr) +{ + RTOSCNTRLDD1_TDeviceData *DeviceDataPrv = (RTOSCNTRLDD1_TDeviceData *)DeviceDataPtr; + + (void)DeviceDataPrv; + PIT_PDD_EnableDevice(PIT_BASE_PTR, PIT_PDD_CHANNEL_0, PDD_DISABLE); + /* Interrupt vector(s) deallocation */ + /* {FreeRTOS RTOS Adapter} Restore interrupt vector: IVT is static, no code is generated */ + PIT_PDD_ModuleClock(PIT_BASE_PTR, PIT_PDD_CLOCK_DISABLED); + /* Unregistration of the device structure */ + PE_LDD_UnregisterDeviceStructure(PE_LDD_COMPONENT_RTOSCNTRLDD1_ID); + /* Deallocation of the device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory deallocation: Dynamic allocation is simulated, no deallocation code is generated */ +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PIT_PDD_EnableDevice(PIT_BASE_PTR, PIT_PDD_CHANNEL_0, PDD_ENABLE); /* Enable the device */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Disable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Disables the component - it stops signal generation and +** events calling. The method is not available if the counter +** can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + PIT_PDD_EnableDevice(PIT_BASE_PTR, PIT_PDD_CHANNEL_0, PDD_DISABLE); + return ERR_OK; +} + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +PE_ISR(RTOSCNTRLDD1_Interrupt) +{ + /* {FreeRTOS RTOS Adapter} ISR parameter is passed through the global variable */ + RTOSCNTRLDD1_TDeviceDataPtr DeviceDataPrv = INT_PIT0__BAREBOARD_RTOS_ISRPARAM; + + PIT_PDD_ClearInterruptFlag(PIT_BASE_PTR, PIT_PDD_CHANNEL_0); /* Clear interrupt flag */ + RTOSCNTRLDD1_OnCounterRestart(DeviceDataPrv->UserDataPtr); /* Invoke OnCounterRestart event */ +} + +/* END RTOSCNTRLDD1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.h new file mode 100644 index 0000000..cc3e48e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTOSCNTRLDD1.h @@ -0,0 +1,260 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTOSCNTRLDD1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 08:06, # CodeGen: 1 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : RTOSCNTRLDD1 +** Module name : PIT +** Counter : PIT_CVAL0 +** Counter direction : Down +** Counter width : 32 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 25 MHz +** Counter restart : On-match +** Period device : PIT_LDVAL0 +** Period : 0.1 ms +** Interrupt : Enabled +** Interrupt : INT_PIT0 +** Interrupt priority : medium priority +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Enabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); +** Deinit - void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); +** Enable - LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); +** Disable - LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file RTOSCNTRLDD1.h +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup RTOSCNTRLDD1_module RTOSCNTRLDD1 module documentation +** @{ +*/ + +#ifndef __RTOSCNTRLDD1_H +#define __RTOSCNTRLDD1_H + +/* MODULE RTOSCNTRLDD1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ + +#include "PIT_PDD.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __BWUserType_RTOSCNTRLDD1_TValueType +#define __BWUserType_RTOSCNTRLDD1_TValueType + typedef uint32_t RTOSCNTRLDD1_TValueType ; /* Type for data parameters of methods */ +#endif +#define RTOSCNTRLDD1_CNT_INP_FREQ_U_0 0x017D7840UL /* Counter input frequency in Hz */ +#define RTOSCNTRLDD1_CNT_INP_FREQ_R_0 25000000.0F /* Counter input frequency in Hz */ +#define RTOSCNTRLDD1_CNT_INP_FREQ_COUNT 0U /* Count of predefined counter input frequencies */ +#define RTOSCNTRLDD1_PERIOD_TICKS 0x09C4UL /* Initialization value of period in 'counter ticks' */ +#define RTOSCNTRLDD1_NUMBER_OF_CHANNELS 0x00U /* Count of predefined channels */ +#define RTOSCNTRLDD1_COUNTER_WIDTH 0x20U /* Counter width in bits */ +#define RTOSCNTRLDD1_COUNTER_DIR DIR_DOWN /* Direction of counting */ +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define RTOSCNTRLDD1_PRPH_BASE_ADDRESS 0x40037000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define RTOSCNTRLDD1_Init_METHOD_ENABLED /*!< Init method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Deinit_METHOD_ENABLED /*!< Deinit method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Enable_METHOD_ENABLED /*!< Enable method of the component RTOSCNTRLDD1 is enabled (generated) */ +#define RTOSCNTRLDD1_Disable_METHOD_ENABLED /*!< Disable method of the component RTOSCNTRLDD1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ +#define RTOSCNTRLDD1_OnCounterRestart_EVENT_ENABLED /*!< OnCounterRestart event of the component RTOSCNTRLDD1 is enabled (generated) */ + + + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* RTOSCNTRLDD1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Deinit (component TimerUnit_LDD) +*/ +/*! +** @brief +** Deinitializes the device. Switches off the device, frees the +** device data structure memory, interrupts vectors, etc. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by Init method +*/ +/* ===================================================================*/ +void RTOSCNTRLDD1_Deinit(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Enable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Enables the component - it starts the signal generation. +** Events may be generated (see SetEventMask). The method is +** not available if the counter can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Enable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Disable (component TimerUnit_LDD) +*/ +/*! +** @brief +** Disables the component - it stops signal generation and +** events calling. The method is not available if the counter +** can't be disabled/enabled by HW. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError RTOSCNTRLDD1_Disable(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : RTOSCNTRLDD1_Interrupt (component TimerUnit_LDD) +** +** Description : +** The method services the interrupt of the selected peripheral(s) +** and eventually invokes event(s) of the component. +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +/* {FreeRTOS RTOS Adapter} ISR function prototype */ +PE_ISR(RTOSCNTRLDD1_Interrupt); + +/* END RTOSCNTRLDD1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __RTOSCNTRLDD1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.c new file mode 100644 index 0000000..c54d507 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.c @@ -0,0 +1,563 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:38, # CodeGen: 15 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 1 +** Number of Down Channels : 1 +** Max Blocked Interrupt Level : 3 +** Syscalls : no +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +/* MODULE RTT1. */ + +#include "RTT1.h" +#include "WAIT1.h" + +/* default standard I/O struct */ +CLS1_ConstStdIOType RTT1_stdio = { + (CLS1_StdIO_In_FctType)RTT1_StdIOReadChar, /* stdin */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stdout */ + (CLS1_StdIO_OutErr_FctType)RTT1_StdIOSendChar, /* stderr */ + RTT1_StdIOKeyPressed /* if input is not empty */ + }; +uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ +/** +int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ +/** +int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ +/** +unsigned RTT1_WriteString(unsigned BufferIndex, const char* s) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ +/** +dword RTT1_GetKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ +/** +long RTT1_WaitKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ +/** +long RTT1_HasKey(void) +{ + Implemented as macro in the header file. +} +*/ + +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ +bool RTT1_StdIOKeyPressed(void) +{ + return RTT1_HasKey()!=0; +} + +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOReadChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + *c = '\0'; + } else { + *c = (uint8_t)res; /* return character */ + } +} + +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ +void RTT1_StdIOSendChar(uint8_t ch) +{ +#if RTT1_CONFIG_BLOCKING_SEND + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 && RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + int timeoutMs = RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS; + #endif + + for(;;) { /* will break */ + if (RTT1_Write(0, (const char*)&ch, 1)==1) { /* non blocking send, check that we were able to send */ + break; /* was able to send character, get out of waiting loop */ + } + #if RTT1_CONFIG_BLOCKING_SEND_WAIT_MS>0 + WAIT1_WaitOSms(RTT1_CONFIG_BLOCKING_SEND_WAIT_MS); + #if RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS>0 + if(timeoutMs<=0) { + break; /* timeout */ + } + timeoutMs -= RTT1_CONFIG_BLOCKING_SEND_WAIT_MS; + #endif + #endif + } /* for */ +#else + (void)RTT1_Write(0, &ch, 1); /* non blocking send, might loose characters */ +#endif +} + +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t RTT1_RecvChar(uint8_t *c) +{ + int res; + + res = RTT1_GetKey(); + if (res==-1) { /* no character present */ + return ERR_RXEMPTY; + } + *c = (uint8_t)res; /* return character */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ +uint8_t RTT1_SendChar(uint8_t ch) +{ + int res; + + res = SEGGER_RTT_Write(0, (const char*)&ch, 1); + if (res!=1) { + return ERR_TXFULL; /* character not sent? */ + } + return ERR_OK; +} + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ +/** +uint16_t RTT1_GetCharsInRxBuf(void) +{ + // Function is implemented as macro in the header file + if (SEGGER_RTT_HasKey()) { + return 1; // at least one available + } + return 0; // none available +} +*/ + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_TerminalOut(char TerminalId, const char* s) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_SetTerminal(char TerminalId) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ +/** +int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char* pBuffer, int BufferSize, int Flags) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ +/** +int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...) +{ + Function is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Deinit(void) +{ + /* noting to de-initialize */ +} + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void RTT1_Init(void) +{ + SEGGER_RTT_Init(); +} + +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void) +{ + return &RTT1_stdio; +} + +/* END RTT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.h new file mode 100644 index 0000000..4136427 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1.h @@ -0,0 +1,476 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : RTT1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : SeggerRTT +** Version : Component 01.089, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** Component name : RTT1 +** Version : V6.32b +** Number of Up Channels : 1 +** Number of Down Channels : 1 +** Max Blocked Interrupt Level : 3 +** Syscalls : no +** Channel 0 : Enabled +** Name : "Terminal" +** Up Buffer Size (Tx) : 512 +** Down Buffer Size (Rx) : 64 +** Up Buffer Mode : Skip (Default) +** Down Buffer Mode : Skip (Default) +** Blocking Send : Enabled +** Timeout (ms) : 5 +** Wait : WAIT1 +** Wait Time (ms) : 1 +** Printf Buffer Size : 64 +** SDK : MCUC1 +** Shell : CLS1 +** Source Folders : +** Source Folder : +** Config Folder : +** Contents : +** Read - int RTT1_Read(unsigned BufferIndex, const char* pBuffer, unsigned NumBytes); +** Write - int RTT1_Write(unsigned BufferIndex, char* pBuffer, unsigned BufferSize); +** WriteString - unsigned RTT1_WriteString(unsigned BufferIndex, const char* s); +** printf - int RTT1_printf(unsigned BufferIndex, const char* sFormat, ...); +** GetKey - dword RTT1_GetKey(void); +** WaitKey - long RTT1_WaitKey(void); +** HasKey - long RTT1_HasKey(void); +** SetTerminal - int RTT1_SetTerminal(char TerminalId); +** TerminalOut - int RTT1_TerminalOut(char TerminalId, const char* s); +** ConfigUpBuffer - int RTT1_ConfigUpBuffer(unsigned BufferIndex, const char* sName, char*... +** ConfigDownBuffer - int RTT1_ConfigDownBuffer(unsigned BufferIndex, const char* sName, char*... +** RecvChar - uint8_t RTT1_RecvChar(uint8_t *c); +** SendChar - uint8_t RTT1_SendChar(uint8_t ch); +** GetCharsInRxBuf - uint16_t RTT1_GetCharsInRxBuf(void); +** StdIOKeyPressed - bool RTT1_StdIOKeyPressed(void); +** StdIOReadChar - void RTT1_StdIOReadChar(uint8_t *c); +** StdIOSendChar - void RTT1_StdIOSendChar(uint8_t ch); +** GetStdio - %@Shell@'ModuleName'%.ConstStdIOTypePtr RTT1_GetStdio(void); +** Deinit - void RTT1_Deinit(void); +** Init - void RTT1_Init(void); +** +** * (c) Copyright Segger, 2019 +** * http : www.segger.com +** * See separate Segger licensing terms. +** * +** * Processor Expert port: Copyright (c) 2016-2019 Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file RTT1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup RTT1_module RTT1 module documentation +** @{ +*/ + +#ifndef __RTT1_H +#define __RTT1_H + +/* MODULE RTT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +/* Include inherited components */ +#include "WAIT1.h" +#include "MCUC1.h" +#include "CLS1.h" + + +#include "SEGGER_RTT.h" + + +#define RTT1_RTT_CHANNEL_0_ENABLED 1 /* 0: channel disabled, 1: channel enabled */ + +extern uint8_t RTT1_DefaultShellBuffer[CLS1_DEFAULT_SHELL_BUFFER_SIZE]; /* default buffer which can be used by the application */ +extern CLS1_ConstStdIOType RTT1_stdio; /* default standard I/O */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define RTT1_Read(BufferIndex, pBuffer, NumBytes) \ + SEGGER_RTT_Read(BufferIndex, pBuffer, NumBytes) + +/* +** =================================================================== +** Method : Read (component SeggerRTT) +** +** Description : +** Read from buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Number of bytes to write +** Returns : +** --- - Number of bytes that have been read +** =================================================================== +*/ + +#define RTT1_Write(BufferIndex, pBuffer, BufferSize) \ + SEGGER_RTT_Write(BufferIndex, pBuffer, BufferSize) + +/* +** =================================================================== +** Method : Write (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * pBuffer - Pointer to buffer +** BufferSize - Size of buffer +** Returns : +** --- - Number of bytes which have been written to +** the up buffer +** =================================================================== +*/ + +#define RTT1_WriteString(BufferIndex, s) \ + SEGGER_RTT_WriteString(BufferIndex, s) + +/* +** =================================================================== +** Method : WriteString (component SeggerRTT) +** +** Description : +** Write to buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer/channel to be used. +** 0 for terminal. +** * s - Pointer to +** Returns : +** --- - Number of bytes which have been stored in +** the "Up"-buffer. +** =================================================================== +*/ + +#define RTT1_GetKey() \ + SEGGER_RTT_GetKey() + +/* +** =================================================================== +** Method : GetKey (component SeggerRTT) +** +** Description : +** Returns a character/key +** Parameters : None +** Returns : +** --- - character code +** =================================================================== +*/ + +#define RTT1_WaitKey() \ + SEGGER_RTT_WaitKey() + +/* +** =================================================================== +** Method : WaitKey (component SeggerRTT) +** +** Description : +** Waits for a key and returns it. +** Parameters : None +** Returns : +** --- - >=0 Character which has been read. +** =================================================================== +*/ + +#define RTT1_HasKey() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : HasKey (component SeggerRTT) +** +** Description : +** Checks if at least one character for reading is available in +** the SEGGER RTT buffer +** Parameters : None +** Returns : +** --- - 0: No characters are available to read; 1: +** At least one character is available. +** =================================================================== +*/ + +bool RTT1_StdIOKeyPressed(void); +/* +** =================================================================== +** Method : StdIOKeyPressed (component SeggerRTT) +** +** Description : +** StdIO handler for Shell +** Parameters : None +** Returns : +** --- - True if there are characters in teh input +** buffer +** =================================================================== +*/ + +void RTT1_StdIOReadChar(uint8_t *c); +/* +** =================================================================== +** Method : StdIOReadChar (component SeggerRTT) +** +** Description : +** StdIO Handler for reading a character. It returns a zero +** byte if there is no character in input buffer. +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : Nothing +** =================================================================== +*/ + +void RTT1_StdIOSendChar(uint8_t ch); +/* +** =================================================================== +** Method : StdIOSendChar (component SeggerRTT) +** +** Description : +** StdIO handler to sends a character. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : Nothing +** =================================================================== +*/ + +uint8_t RTT1_RecvChar(uint8_t *c); +/* +** =================================================================== +** Method : RecvChar (component SeggerRTT) +** +** Description : +** Receives a character from channel 0. Returns ERR_RXEMPTY if +** no character available +** Parameters : +** NAME - DESCRIPTION +** * c - Pointer to where to store the received +** character +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t RTT1_SendChar(uint8_t ch); +/* +** =================================================================== +** Method : SendChar (component SeggerRTT) +** +** Description : +** Sends a character to channel 0. +** Parameters : +** NAME - DESCRIPTION +** ch - Character to send +** Returns : +** --- - Error code. ERR_OK if character has been +** sent, ERR_TXFULL otherwise. +** =================================================================== +*/ + +#define RTT1_GetCharsInRxBuf() \ + SEGGER_RTT_HasKey() + +/* +** =================================================================== +** Method : GetCharsInRxBuf (component SeggerRTT) +** +** Description : +** Returns the number of characters in the receive buffer. +** Parameters : None +** Returns : +** --- - Number of characters in the input buffer, +** zero for none available. +** =================================================================== +*/ + +void RTT1_Init(void); + +/* +** =================================================================== +** Method : Init (component SeggerRTT) +** +** Description : +** Initializes the RTT Control Block. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +#define RTT1_TerminalOut(TerminalId, s) \ + SEGGER_RTT_TerminalOut(TerminalId, s) + +/* +** =================================================================== +** Method : TerminalOut (component SeggerRTT) +** +** Description : +** Writes a string to the given terminal without changing the +** terminal for channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - TerminalId, 0..15 +** * s - Pointer to string +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_SetTerminal(TerminalId) \ + SEGGER_RTT_SetTerminal(TerminalId) + +/* +** =================================================================== +** Method : SetTerminal (component SeggerRTT) +** +** Description : +** Sets the terminal to be used for output on channel 0. +** Parameters : +** NAME - DESCRIPTION +** TerminalId - Terminal ID, 0..15 +** Returns : +** --- - Error code +** =================================================================== +*/ + +#define RTT1_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigUpBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigUpBuffer (component SeggerRTT) +** +** Description : +** Configures the Up (device to host) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) \ + SEGGER_RTT_ConfigDownBuffer(BufferIndex, sName, pBuffer, BufferSize, Flags) + +/* +** =================================================================== +** Method : ConfigDownBuffer (component SeggerRTT) +** +** Description : +** Configures the Down (host to device) buffer +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Buffer index +** sName - Buffer name +** * pBuffer - Pointer to buffer +** intBufferSize - Size of buffer in bytes +** Flags - SEGGER_RTT_MODE_NO_BLOCK_SKIP, +** SEGGER_RTT_MODE_NO_BLOCK_TRIM or +** SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL +** Returns : +** --- - Error code, >=0 OK, <0 Error +** =================================================================== +*/ + +#define RTT1_printf \ + SEGGER_RTT_printf + +/* +** =================================================================== +** Method : printf (component SeggerRTT) +** +** Description : +** Stores a formatted string in SEGGER RTT control block. This +** data is sent to the host. +** Parameters : +** NAME - DESCRIPTION +** BufferIndex - Index of "Up"-buffer to be +** used. (e.g. 0 for "Terminal") +** sFormat - Pointer to format string, followed +** by the arguments for conversion +** Returns : +** --- - Error code +** =================================================================== +*/ + +void RTT1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component SeggerRTT) +** +** Description : +** Driver deinitialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +CLS1_ConstStdIOTypePtr RTT1_GetStdio(void); +/* +** =================================================================== +** Method : GetStdio (component SeggerRTT) +** +** Description : +** Returns a pointer to the standard I/O +** Parameters : None +** Returns : +** --- - Error code +** =================================================================== +*/ + +/* END RTT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __RTT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1config.h new file mode 100644 index 0000000..0e2e01a --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT1config.h @@ -0,0 +1,56 @@ +/** + * \file + * \brief Configuration header file for Segger RTT + * + * This header file is used to configure settings of the Segger RTT Module. + */ + +#ifndef __RTT1_CONFIG_H +#define __RTT1_CONFIG_H + +#ifndef RTT1_CONFIG_PROVIDE_SYSCALLS + #define RTT1_CONFIG_PROVIDE_SYSCALLS (0) + /*!< 1: RTT library implements SysCalls; 0: no Syscalls implemented */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND + #define RTT1_CONFIG_BLOCKING_SEND (1) + /*!< 1: using blocking call for stdio calls; 0: do not using blocking calls */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS + #define RTT1_CONFIG_BLOCKING_SEND_TIMEOUT_MS (5) + /*!< Timeout value for blocking calls for sending. Use zero for no timeout */ +#endif + +#ifndef RTT1_CONFIG_BLOCKING_SEND_WAIT_MS + #define RTT1_CONFIG_BLOCKING_SEND_WAIT_MS (1) + /*!< Waiting time during blocking send. Use zero for no waiting time */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_UP + #define RTT1_CONFIG_RTT_BUFFER_SIZE_UP (512) + /*!< Size of the up (Tx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN + #define RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN (64) + /*!< Size of the down (Rx on the target side) buffer in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF + #define RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF (64) + /*!< Size of the buffer for RTT printf() in bytes */ +#endif + +#ifndef RTT1_CONFIG_RTT_UP_BUFFER_MODE + #define RTT1_CONFIG_RTT_UP_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#ifndef RTT1_CONFIG_RTT_DOWN_BUFFER_MODE + #define RTT1_CONFIG_RTT_DOWN_BUFFER_MODE (SEGGER_RTT_MODE_NO_BLOCK_SKIP) + /*!< Up buffer mode: SEGGER_RTT_MODE_NO_BLOCK_SKIP, SEGGER_RTT_MODE_NO_BLOCK_TRIM or SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL */ +#endif + +#endif /* __RTT1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT_Syscalls_GCC.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT_Syscalls_GCC.c new file mode 100644 index 0000000..9ebed3e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/RTT_Syscalls_GCC.c @@ -0,0 +1,203 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Syscalls_GCC.c +Purpose : Low-level functions for using printf() via RTT in GCC. + To use RTT for printf output, include this file in your + application. +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#if (defined __GNUC__) && !(defined __SES_ARM) && !(defined __CROSSWORKS_ARM) + +#if 0 /* << EST moved to below */ +#include // required for _write_r +#endif +#include "SEGGER_RTT.h" + +#if RTT1_CONFIG_PROVIDE_SYSCALLS /* << EST */ +#include /* for EOF */ /* << EST */ +#include // required for _write_r // << EST moved from above + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// If necessary define the _reent struct +// to match the one passed by the used standard library. +// +struct _reent; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +#if 0 +int _write(int file, char *ptr, int len); +int _write_r(struct _reent *r, int file, const void *ptr, int len); +#else /* << EST */ +extern int _write(int file, char *ptr, int len); +extern _ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len); +#endif + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _write() +* +* Function description +* Low-level write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +int _write(int file, char *ptr, int len) { + (void) file; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +/********************************************************************* +* +* _write_r() +* +* Function description +* Low-level reentrant write function. +* libc subroutines will use this system routine for output to all files, +* including stdout. +* Write data via RTT. +*/ +#if 0 +int _write_r(struct _reent *r, int file, const void *ptr, int len) { +#else /* << EST */ +_ssize_t _write_r(struct _reent *r, int file, const void *ptr, size_t len) { +#endif + (void) file; /* Not used, avoid warning */ + (void) r; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, ptr, len); + return len; +} + +int _putc(int c, __FILE *fp) { /* << EST */ + char ch = c; + (void)fp; /* Not used, avoid warning */ + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _putchar(int c) { /* << EST */ + char ch = c; + SEGGER_RTT_Write(0, &ch, 1); + return 1; +} + +int _getc(__FILE *fp) { /* << EST */ + char ch; + (void)fp; /* Not used, avoid warning */ + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return ch; +} + +int _read(void) { + uint8_t ch; + if (SEGGER_RTT_Read(0, &ch, 1)==0) { + return EOF; + } + return (int)ch; +} + +int __attribute__((weak)) _isatty(int file __attribute__((unused))) { + return 1; +} + +int __attribute__((weak)) _close(int fildes __attribute__((unused))) { + return -1; +} + +int __attribute__((weak)) _lseek(int file __attribute__((unused)), int ptr __attribute__((unused)), int dir __attribute__((unused))) { + return -1; +} + +#if 0 +int __attribute__((weak)) _fstat (int fd __attribute__((unused)), struct stat *st) +{ + memset (st, 0, sizeof(*st)); + st->st_mode = S_IFCHR; + return 0; +} +#endif + + +#endif /* RTT1_CONFIG_PROVIDE_SYSCALLS */ /* << EST */ + +#endif +/****** End Of File *************************************************/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.c new file mode 100644 index 0000000..1f6a596 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.c @@ -0,0 +1,1784 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.c +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 10887 $ + +Additional information: + Type "int" is assumed to be 32-bits in size + H->T Host to target communication + T->H Target to host communication + + RTT channel 0 is always present and reserved for Terminal usage. + Name is fixed to "Terminal" + + Effective buffer size: SizeOfBuffer - 1 + + WrOff == RdOff: Buffer is empty + WrOff == (RdOff - 1): Buffer is full + WrOff > RdOff: Free space includes wrap-around + WrOff < RdOff: Used space includes wrap-around + (WrOff == (SizeOfBuffer - 1)) && (RdOff == 0): + Buffer full and wrap-around after next byte + + +---------------------------------------------------------------------- +*/ + +#include "SEGGER_RTT.h" + +#include // for memcpy + +/********************************************************************* +* +* Configuration, default values +* +********************************************************************** +*/ + +#ifndef BUFFER_SIZE_UP + #define BUFFER_SIZE_UP 1024 // Size of the buffer for terminal output of target, up to host +#endif + +#ifndef BUFFER_SIZE_DOWN + #define BUFFER_SIZE_DOWN 16 // Size of the buffer for terminal input to target from host (Usually keyboard input) +#endif + +#ifndef SEGGER_RTT_MAX_NUM_UP_BUFFERS + #define SEGGER_RTT_MAX_NUM_UP_BUFFERS 2 // Number of up-buffers (T->H) available on this target +#endif + +#ifndef SEGGER_RTT_MAX_NUM_DOWN_BUFFERS + #define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS 2 // Number of down-buffers (H->T) available on this target +#endif + +#ifndef SEGGER_RTT_BUFFER_SECTION + #if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_BUFFER_SECTION SEGGER_RTT_SECTION + #endif +#endif + +#ifndef SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGNMENT 0 +#endif + +#ifndef SEGGER_RTT_MODE_DEFAULT + #define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP +#endif + +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() +#endif + +#ifndef STRLEN + #define STRLEN(a) strlen((a)) +#endif + +#ifndef SEGGER_RTT_MEMCPY_USE_BYTELOOP + #define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 +#endif + +#ifndef SEGGER_RTT_MEMCPY + #ifdef MEMCPY + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) MEMCPY((pDest), (pSrc), (NumBytes)) + #else + #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) memcpy((pDest), (pSrc), (NumBytes)) + #endif +#endif + +#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX + #define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +// +// For some environments, NULL may not be defined until certain headers are included +// +#ifndef NULL + #define NULL 0 +#endif + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ +#if (defined __ICCARM__) || (defined __ICCRX__) + #define RTT_PRAGMA(P) _Pragma(#P) +#endif + +#if SEGGER_RTT_ALIGNMENT || SEGGER_RTT_BUFFER_ALIGNMENT + #if (defined __GNUC__) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #elif (defined __ICCARM__) || (defined __ICCRX__) + #define PRAGMA(A) _Pragma(#A) +#define SEGGER_RTT_ALIGN(Var, Alignment) RTT_PRAGMA(data_alignment=Alignment) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_ALIGN(Var, Alignment) Var __attribute__ ((aligned (Alignment))) + #else + #error "Alignment not supported for this compiler." + #endif +#else + #define SEGGER_RTT_ALIGN(Var, Alignment) Var +#endif + +#if defined(SEGGER_RTT_SECTION) || defined (SEGGER_RTT_BUFFER_SECTION) + #if (defined __GNUC__) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section))) Var + #elif (defined __ICCARM__) || (defined __ICCRX__) +#define SEGGER_RTT_PUT_SECTION(Var, Section) RTT_PRAGMA(location=Section) \ + Var + #elif (defined __CC_ARM) + #define SEGGER_RTT_PUT_SECTION(Var, Section) __attribute__ ((section (Section), zero_init)) Var + #else + #error "Section placement not supported for this compiler." + #endif +#else + #define SEGGER_RTT_PUT_SECTION(Var, Section) Var +#endif + + +#if SEGGER_RTT_ALIGNMENT + #define SEGGER_RTT_CB_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_ALIGNMENT) +#else + #define SEGGER_RTT_CB_ALIGN(Var) Var +#endif + +#if SEGGER_RTT_BUFFER_ALIGNMENT + #define SEGGER_RTT_BUFFER_ALIGN(Var) SEGGER_RTT_ALIGN(Var, SEGGER_RTT_BUFFER_ALIGNMENT) +#else + #define SEGGER_RTT_BUFFER_ALIGN(Var) Var +#endif + + +#if defined(SEGGER_RTT_SECTION) + #define SEGGER_RTT_PUT_CB_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_SECTION) +#else + #define SEGGER_RTT_PUT_CB_SECTION(Var) Var +#endif + +#if defined(SEGGER_RTT_BUFFER_SECTION) + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) SEGGER_RTT_PUT_SECTION(Var, SEGGER_RTT_BUFFER_SECTION) +#else + #define SEGGER_RTT_PUT_BUFFER_SECTION(Var) Var +#endif + +/********************************************************************* +* +* Static const data +* +********************************************************************** +*/ + +static unsigned char _aTerminalId[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +// +// RTT Control Block and allocate buffers for channel 0 +// +SEGGER_RTT_PUT_CB_SECTION(SEGGER_RTT_CB_ALIGN(SEGGER_RTT_CB _SEGGER_RTT)); + +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acUpBuffer [BUFFER_SIZE_UP])); +SEGGER_RTT_PUT_BUFFER_SECTION(SEGGER_RTT_BUFFER_ALIGN(static char _acDownBuffer[BUFFER_SIZE_DOWN])); + +static char _ActiveTerminal; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ + +/********************************************************************* +* +* _DoInit() +* +* Function description +* Initializes the control block an buffers. +* May only be called via INIT() to avoid overriding settings. +* +*/ +#define INIT() do { \ + if (_SEGGER_RTT.acID[0] == '\0') { _DoInit(); } \ + } while (0) +static void _DoInit(void) { + SEGGER_RTT_CB* p; + // + // Initialize control block + // + p = &_SEGGER_RTT; + p->MaxNumUpBuffers = SEGGER_RTT_MAX_NUM_UP_BUFFERS; + p->MaxNumDownBuffers = SEGGER_RTT_MAX_NUM_DOWN_BUFFERS; + // + // Initialize up buffer 0 + // + p->aUp[0].sName = "Terminal"; + p->aUp[0].pBuffer = _acUpBuffer; + p->aUp[0].SizeOfBuffer = sizeof(_acUpBuffer); + p->aUp[0].RdOff = 0u; + p->aUp[0].WrOff = 0u; +#if 1 /* << EST */ + p->aUp[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_UP; +#else + p->aUp[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Initialize down buffer 0 + // + p->aDown[0].sName = "Terminal"; + p->aDown[0].pBuffer = _acDownBuffer; + p->aDown[0].SizeOfBuffer = sizeof(_acDownBuffer); + p->aDown[0].RdOff = 0u; + p->aDown[0].WrOff = 0u; +#if 1 /* << EST */ + p->aDown[0].Flags = SEGGER_RTT_CHANNEL_0_MODE_DOWN; +#else + p->aDown[0].Flags = SEGGER_RTT_MODE_DEFAULT; +#endif + // + // Finish initialization of the control block. + // Copy Id string in three steps to make sure "SEGGER RTT" is not found + // in initializer memory (usually flash) by J-Link + // + strcpy(&p->acID[7], "RTT"); + strcpy(&p->acID[0], "SEGGER"); + p->acID[6] = ' '; +} + +/********************************************************************* +* +* _WriteBlocking() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* The caller is responsible for managing the write chunk sizes as +* _WriteBlocking() will block until all data has been posted successfully. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* >= 0 - Number of bytes written into buffer. +*/ +static unsigned _WriteBlocking(SEGGER_RTT_BUFFER_UP* pRing, const char* pBuffer, unsigned NumBytes) { + unsigned NumBytesToWrite; + unsigned NumBytesWritten; + unsigned RdOff; + unsigned WrOff; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + // + // Write data to buffer and handle wrap-around if necessary + // + NumBytesWritten = 0u; + WrOff = pRing->WrOff; + do { + RdOff = pRing->RdOff; // May be changed by host (debug probe) in the meantime + if (RdOff > WrOff) { + NumBytesToWrite = RdOff - WrOff - 1u; + } else { + NumBytesToWrite = pRing->SizeOfBuffer - (WrOff - RdOff + 1u); + } + NumBytesToWrite = MIN(NumBytesToWrite, (pRing->SizeOfBuffer - WrOff)); // Number of bytes that can be written until buffer wrap-around + NumBytesToWrite = MIN(NumBytesToWrite, NumBytes); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesWritten += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; + while (NumBytesToWrite--) { + *pDst++ = *pBuffer++; + }; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pBuffer, NumBytesToWrite); + NumBytesWritten += NumBytesToWrite; + pBuffer += NumBytesToWrite; + NumBytes -= NumBytesToWrite; + WrOff += NumBytesToWrite; +#endif + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0u; + } + pRing->WrOff = WrOff; + } while (NumBytes); + // + return NumBytesWritten; +} + +/********************************************************************* +* +* _WriteNoCheck() +* +* Function description +* Stores a specified number of characters in SEGGER RTT ring buffer +* and updates the associated write pointer which is periodically +* read by the host. +* It is callers responsibility to make sure data actually fits in buffer. +* +* Parameters +* pRing Ring buffer to post to. +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there might not be enough space in the "Up"-buffer, call _WriteBlocking +*/ +static void _WriteNoCheck(SEGGER_RTT_BUFFER_UP* pRing, const char* pData, unsigned NumBytes) { + unsigned NumBytesAtOnce; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + WrOff = pRing->WrOff; + Rem = pRing->SizeOfBuffer - WrOff; + if (Rem > NumBytes) { + // + // All data fits before wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytesAtOnce = Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pDst = pRing->pBuffer; + NumBytesAtOnce = NumBytes - Rem; + while (NumBytesAtOnce--) { + *pDst++ = *pData++; + }; + pRing->WrOff = NumBytes - Rem; +#else + NumBytesAtOnce = Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytesAtOnce); + NumBytesAtOnce = NumBytes - Rem; + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytesAtOnce); + pRing->WrOff = NumBytesAtOnce; +#endif + } +} + +/********************************************************************* +* +* _PostTerminalSwitch() +* +* Function description +* Switch terminal to the given terminal ID. It is the caller's +* responsibility to ensure the terminal ID is correct and there is +* enough space in the buffer for this to complete successfully. +* +* Parameters +* pRing Ring buffer to post to. +* TerminalId Terminal ID to switch to. +*/ +static void _PostTerminalSwitch(SEGGER_RTT_BUFFER_UP* pRing, unsigned char TerminalId) { + unsigned char ac[2]; + + ac[0] = 0xFFu; + ac[1] = _aTerminalId[TerminalId]; // Caller made already sure that TerminalId does not exceed our terminal limit + _WriteBlocking(pRing, (const char*)ac, 2u); +} + +/********************************************************************* +* +* _GetAvailWriteSpace() +* +* Function description +* Returns the number of bytes that can be written to the ring +* buffer without blocking. +* +* Parameters +* pRing Ring buffer to check. +* +* Return value +* Number of bytes that are free in the buffer. +*/ +static unsigned _GetAvailWriteSpace(SEGGER_RTT_BUFFER_UP* pRing) { + unsigned RdOff; + unsigned WrOff; + unsigned r; + // + // Avoid warnings regarding volatile access order. It's not a problem + // in this case, but dampen compiler enthusiasm. + // + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + if (RdOff <= WrOff) { + r = pRing->SizeOfBuffer - 1u - WrOff + RdOff; + } else { + r = RdOff - WrOff - 1u; + } + return r; +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_ReadNoLock() +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* Do not lock against interrupts and multiple access. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_ReadNoLock(unsigned BufferIndex, void* pData, unsigned BufferSize) { + unsigned NumBytesRem; + unsigned NumBytesRead; + unsigned RdOff; + unsigned WrOff; + unsigned char* pBuffer; + SEGGER_RTT_BUFFER_DOWN* pRing; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + const char* pSrc; +#endif + // + INIT(); + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + pBuffer = (unsigned char*)pData; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + NumBytesRead = 0u; + // + // Read from current read position to wrap-around of buffer, first + // + if (RdOff > WrOff) { + NumBytesRem = pRing->SizeOfBuffer - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + // + // Handle wrap-around of buffer + // + if (RdOff == pRing->SizeOfBuffer) { + RdOff = 0u; + } + } + // + // Read remaining items of buffer + // + NumBytesRem = WrOff - RdOff; + NumBytesRem = MIN(NumBytesRem, BufferSize); + if (NumBytesRem > 0u) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pSrc = pRing->pBuffer + RdOff; + NumBytesRead += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; + while (NumBytesRem--) { + *pBuffer++ = *pSrc++; + }; +#else + SEGGER_RTT_MEMCPY(pBuffer, pRing->pBuffer + RdOff, NumBytesRem); + NumBytesRead += NumBytesRem; + pBuffer += NumBytesRem; + BufferSize -= NumBytesRem; + RdOff += NumBytesRem; +#endif + } + if (NumBytesRead) { + pRing->RdOff = RdOff; + } + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_Read +* +* Function description +* Reads characters from SEGGER real-time-terminal control block +* which have been previously stored by the host. +* +* Parameters +* BufferIndex Index of Down-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to buffer provided by target application, to copy characters from RTT-down-buffer to. +* BufferSize Size of the target application buffer. +* +* Return value +* Number of bytes that have been read. +*/ +unsigned SEGGER_RTT_Read(unsigned BufferIndex, void* pBuffer, unsigned BufferSize) { + unsigned NumBytesRead; + // + SEGGER_RTT_LOCK(); + // + // Call the non-locking read function + // + NumBytesRead = SEGGER_RTT_ReadNoLock(BufferIndex, pBuffer, BufferSize); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return NumBytesRead; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteWithOverwriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block. +* SEGGER_RTT_WriteWithOverwriteNoLock does not lock the application +* and overwrites data if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, data is overwritten. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +* (3) Do not use SEGGER_RTT_WriteWithOverwriteNoLock if a J-Link +* connection reads RTT data. +*/ +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Check if we will overwrite data and need to adjust the RdOff. + // + if (pRing->WrOff == pRing->RdOff) { + Avail = pRing->SizeOfBuffer - 1u; + } else if ( pRing->WrOff < pRing->RdOff) { + Avail = pRing->RdOff - pRing->WrOff - 1u; + } else { + Avail = pRing->RdOff - pRing->WrOff - 1u + pRing->SizeOfBuffer; + } + if (NumBytes > Avail) { + pRing->RdOff += (NumBytes - Avail); + while (pRing->RdOff >= pRing->SizeOfBuffer) { + pRing->RdOff -= pRing->SizeOfBuffer; + } + } + // + // Write all data, no need to check the RdOff, but possibly handle multiple wrap-arounds + // + Avail = pRing->SizeOfBuffer - pRing->WrOff; + do { + if (Avail > NumBytes) { + // + // Last round + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + Avail = NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff += Avail; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, NumBytes); + pRing->WrOff += NumBytes; +#endif + break; + } else { + // + // Wrap-around necessary, write until wrap-around and reset WrOff + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + pRing->WrOff; + NumBytes -= Avail; + while (Avail--) { + *pDst++ = *pData++; + }; + pRing->WrOff = 0; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + pRing->WrOff, pData, Avail); + pData += Avail; + pRing->WrOff = 0; + NumBytes -= Avail; +#endif + Avail = (pRing->SizeOfBuffer - 1); + } + } while (NumBytes); +} + +/********************************************************************* +* +* SEGGER_RTT_WriteSkipNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteSkipNoLock does not lock the application and +* skips all data, if the data does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, all data is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteSkipNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + unsigned RdOff; + unsigned WrOff; + unsigned Rem; +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + char* pDst; +#endif + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer and copy some elements into local variables. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + RdOff = pRing->RdOff; + WrOff = pRing->WrOff; + // + // Handle the most common cases fastest. + // Which is: + // RdOff <= WrOff -> Space until wrap around is free. + // AND + // WrOff + NumBytes < SizeOfBuffer -> No Wrap around necessary. + // + // OR + // + // RdOff > WrOff -> Space until RdOff - 1 is free. + // AND + // WrOff + NumBytes < RdOff -> Data fits into buffer + // + if (RdOff <= WrOff) { + // + // Get space until WrOff will be at wrap around. + // + Avail = pRing->SizeOfBuffer - 1u - WrOff ; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + // + // If data did not fit into space until wrap around calculate complete space in buffer. + // + Avail += RdOff; + // + // If there is still no space for the whole of this output, don't bother. + // + if (Avail >= NumBytes) { + // + // OK, we have enough space in buffer. Copy in one or 2 chunks + // + Rem = pRing->SizeOfBuffer - WrOff; // Space until end of buffer + if (Rem > NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + } else { + // + // We reach the end of the buffer, so need to wrap around + // +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + NumBytes -= Rem; + WrOff = NumBytes; + do { + *pDst++ = *pData++; + } while (--Rem); + pDst = pRing->pBuffer; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, Rem); + SEGGER_RTT_MEMCPY(pRing->pBuffer, pData + Rem, NumBytes - Rem); + pRing->WrOff = NumBytes - Rem; +#endif + } + return 1; + } + } else { + Avail = RdOff - WrOff - 1u; + if (Avail >= NumBytes) { +#if SEGGER_RTT_MEMCPY_USE_BYTELOOP + pDst = pRing->pBuffer + WrOff; + WrOff += NumBytes; + while (NumBytes--) { + *pDst++ = *pData++; + }; + pRing->WrOff = WrOff; +#else + SEGGER_RTT_MEMCPY(pRing->pBuffer + WrOff, pData, NumBytes); + pRing->WrOff = WrOff + NumBytes; +#endif + return 1; + } + } + // + // If we reach this point no data has been written + // + return 0; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteNoLock +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* SEGGER_RTT_WriteNoLock does not lock the application. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ +unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + unsigned Avail; + const char* pData; + SEGGER_RTT_BUFFER_UP* pRing; + + pData = (const char *)pBuffer; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // How we output depends upon the mode... + // + switch (pRing->Flags) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother. + // + Avail = _GetAvailWriteSpace(pRing); + if (Avail < NumBytes) { + Status = 0u; + } else { + Status = NumBytes; + _WriteNoCheck(pRing, pData, NumBytes); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode, trim to what we can output without blocking. + // + Avail = _GetAvailWriteSpace(pRing); + Status = Avail < NumBytes ? Avail : NumBytes; + _WriteNoCheck(pRing, pData, Status); + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + Status = _WriteBlocking(pRing, pData, NumBytes); + break; + default: + Status = 0u; + break; + } + // + // Finish up. + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_Write +* +* Function description +* Stores a specified number of characters in SEGGER RTT +* control block which is then read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* pBuffer Pointer to character array. Does not need to point to a \0 terminated string. +* NumBytes Number of bytes to be stored in the SEGGER RTT control block. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ +unsigned SEGGER_RTT_Write(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes) { + unsigned Status; + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Call the non-locking write function + // + Status = SEGGER_RTT_WriteNoLock(BufferIndex, pBuffer, NumBytes); + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_WriteString +* +* Function description +* Stores string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* s Pointer to string. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +* (2) String passed to this function has to be \0 terminated +* (3) \0 termination character is *not* stored in RTT buffer +*/ +unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char* s) { + unsigned Len; + + Len = STRLEN(s); + return SEGGER_RTT_Write(BufferIndex, s, Len); +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkipNoLock +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* SEGGER_RTT_PutCharSkipNoLock does not lock the application and +* skips the byte, if it does not fit into the buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +* (2) For performance reasons this function does not call Init() +* and may only be called after RTT has been initialized. +* Either by calling SEGGER_RTT_Init() or calling another RTT API function first. +*/ + +unsigned SEGGER_RTT_PutCharSkipNoLock(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_PutCharSkip +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) If there is not enough space in the "Up"-buffer, the character is dropped. +*/ + +unsigned SEGGER_RTT_PutCharSkip(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + + /********************************************************************* +* +* SEGGER_RTT_PutChar +* +* Function description +* Stores a single character/byte in SEGGER RTT buffer. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used (e.g. 0 for "Terminal"). +* c Byte to be stored. +* +* Return value +* Number of bytes which have been stored in the "Up"-buffer. +* +* Notes +* (1) Data is stored according to buffer flags. +*/ + +unsigned SEGGER_RTT_PutChar(unsigned BufferIndex, char c) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned WrOff; + unsigned Status; + // + // Prepare + // + INIT(); + SEGGER_RTT_LOCK(); + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + // + // Get write position and handle wrap-around if necessary + // + WrOff = pRing->WrOff + 1; + if (WrOff == pRing->SizeOfBuffer) { + WrOff = 0; + } + // + // Wait for free space if mode is set to blocking + // + if (pRing->Flags == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + while (WrOff == pRing->RdOff) { + ; + } + } + // + // Output byte if free space is available + // + if (WrOff != pRing->RdOff) { + pRing->pBuffer[pRing->WrOff] = c; + pRing->WrOff = WrOff; + Status = 1; + } else { + Status = 0; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + // + return Status; +} + +/********************************************************************* +* +* SEGGER_RTT_GetKey +* +* Function description +* Reads one character from the SEGGER RTT buffer. +* Host has previously stored data there. +* +* Return value +* < 0 - No character available (buffer empty). +* >= 0 - Character which has been read. (Possible values: 0 - 255) +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0. +*/ +int SEGGER_RTT_GetKey(void) { + char c; + int r; + + r = (int)SEGGER_RTT_Read(0u, &c, 1u); + if (r == 1) { + r = (int)(unsigned char)c; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_WaitKey +* +* Function description +* Waits until at least one character is avaible in the SEGGER RTT buffer. +* Once a character is available, it is read and this function returns. +* +* Return value +* >=0 - Character which has been read. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +* (2) This function is blocking if no character is present in RTT buffer +*/ +int SEGGER_RTT_WaitKey(void) { + int r; + + do { + r = SEGGER_RTT_GetKey(); + } while (r < 0); + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasKey +* +* Function description +* Checks if at least one character for reading is available in the SEGGER RTT buffer. +* +* Return value +* == 0 - No characters are available to read. +* == 1 - At least one character is available. +* +* Notes +* (1) This function is only specified for accesses to RTT buffer 0 +*/ +int SEGGER_RTT_HasKey(void) { + unsigned RdOff; + int r; + + INIT(); + RdOff = _SEGGER_RTT.aDown[0].RdOff; + if (RdOff != _SEGGER_RTT.aDown[0].WrOff) { + r = 1; + } else { + r = 0; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_HasData +* +* Function description +* Check if there is data from the host in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasData(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_DOWN* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aDown[BufferIndex]; + v = pRing->WrOff; + return v - pRing->RdOff; +} + +/********************************************************************* +* +* SEGGER_RTT_HasDataUp +* +* Function description +* Check if there is data remaining to be sent in the given buffer. +* +* Return value: +* ==0: No data +* !=0: Data in buffer +* +*/ +unsigned SEGGER_RTT_HasDataUp(unsigned BufferIndex) { + SEGGER_RTT_BUFFER_UP* pRing; + unsigned v; + + pRing = &_SEGGER_RTT.aUp[BufferIndex]; + v = pRing->RdOff; + return pRing->WrOff - v; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocDownBuffer +* +* Function description +* Run-time configuration of the next down-buffer (H->T). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocDownBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aDown[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumDownBuffers) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_AllocUpBuffer +* +* Function description +* Run-time configuration of the next up-buffer (T->H). +* The next buffer, which is not used yet is configured. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. Buffer Index +* < 0 - Error +*/ +int SEGGER_RTT_AllocUpBuffer(const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int BufferIndex; + + INIT(); + SEGGER_RTT_LOCK(); + BufferIndex = 0; + do { + if (_SEGGER_RTT.aUp[BufferIndex].pBuffer == NULL) { + break; + } + BufferIndex++; + } while (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers); + if (BufferIndex < _SEGGER_RTT.MaxNumUpBuffers) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + } else { + BufferIndex = -1; + } + SEGGER_RTT_UNLOCK(); + return BufferIndex; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer (T->H). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 - O.K. +* < 0 - Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigUpBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + _SEGGER_RTT.aUp[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aUp[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aUp[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aUp[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_ConfigDownBuffer +* +* Function description +* Run-time configuration of a specific down-buffer (H->T). +* Buffer to be configured is specified by index. +* This includes: Buffer address, size, name, flags, ... +* +* Parameters +* BufferIndex Index of the buffer to configure. +* sName Pointer to a constant name string. +* pBuffer Pointer to a buffer to be used. +* BufferSize Size of the buffer. +* Flags Operating modes. Define behavior if buffer is full (not enough space for entire message). +* +* Return value +* >= 0 O.K. +* < 0 Error +* +* Additional information +* Buffer 0 is configured on compile-time. +* May only be called once per buffer. +* Buffer name and flags can be reconfigured using the appropriate functions. +*/ +int SEGGER_RTT_ConfigDownBuffer(unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + if (BufferIndex > 0u) { + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + _SEGGER_RTT.aDown[BufferIndex].pBuffer = (char*)pBuffer; + _SEGGER_RTT.aDown[BufferIndex].SizeOfBuffer = BufferSize; + _SEGGER_RTT.aDown[BufferIndex].RdOff = 0u; + _SEGGER_RTT.aDown[BufferIndex].WrOff = 0u; + } + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameUpBuffer +* +* Function description +* Run-time configuration of a specific up-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameUpBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetNameDownBuffer +* +* Function description +* Run-time configuration of a specific Down-buffer name (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* sName Pointer to a constant name string. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetNameDownBuffer(unsigned BufferIndex, const char* sName) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].sName = sName; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsUpBuffer +* +* Function description +* Run-time configuration of specific up-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsUpBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumUpBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aUp[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_SetFlagsDownBuffer +* +* Function description +* Run-time configuration of specific Down-buffer flags (T->H). +* Buffer to be configured is specified by index. +* +* Parameters +* BufferIndex Index of the buffer to renamed. +* Flags Flags to set for the buffer. +* +* Return value +* >= 0 O.K. +* < 0 Error +*/ +int SEGGER_RTT_SetFlagsDownBuffer(unsigned BufferIndex, unsigned Flags) { + int r; + + INIT(); + if (BufferIndex < (unsigned)_SEGGER_RTT.MaxNumDownBuffers) { + SEGGER_RTT_LOCK(); + _SEGGER_RTT.aDown[BufferIndex].Flags = Flags; + SEGGER_RTT_UNLOCK(); + r = 0; + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_Init +* +* Function description +* Initializes the RTT Control Block. +* Should be used in RAM targets, at start of the application. +* +*/ +void SEGGER_RTT_Init (void) { + _DoInit(); +} + +/********************************************************************* +* +* SEGGER_RTT_SetTerminal +* +* Function description +* Sets the terminal to be used for output on channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* +* Return value +* >= 0 O.K. +* < 0 Error (e.g. if RTT is configured for non-blocking mode and there was no space in the buffer to set the new terminal Id) +*/ +int SEGGER_RTT_SetTerminal (char TerminalId) { + unsigned char ac[2]; + SEGGER_RTT_BUFFER_UP* pRing; + unsigned Avail; + int r; + // + INIT(); + // + r = 0; + ac[0] = 0xFFu; + if ((unsigned char)TerminalId < (unsigned char)sizeof(_aTerminalId)) { // We only support a certain number of channels + ac[1] = _aTerminalId[(unsigned char)TerminalId]; + pRing = &_SEGGER_RTT.aUp[0]; // Buffer 0 is always reserved for terminal I/O, so we can use index 0 here, fixed + SEGGER_RTT_LOCK(); // Lock to make sure that no other task is writing into buffer, while we are and number of free bytes in buffer does not change downwards after checking and before writing + if ((pRing->Flags & SEGGER_RTT_MODE_MASK) == SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) { + _ActiveTerminal = TerminalId; + _WriteBlocking(pRing, (const char*)ac, 2u); + } else { // Skipping mode or trim mode? => We cannot trim this command so handling is the same for both modes + Avail = _GetAvailWriteSpace(pRing); + if (Avail >= 2) { + _ActiveTerminal = TerminalId; // Only change active terminal in case of success + _WriteNoCheck(pRing, (const char*)ac, 2u); + } else { + r = -1; + } + } + SEGGER_RTT_UNLOCK(); + } else { + r = -1; + } + return r; +} + +/********************************************************************* +* +* SEGGER_RTT_TerminalOut +* +* Function description +* Writes a string to the given terminal +* without changing the terminal for channel 0. +* +* Parameters +* TerminalId Index of the terminal. +* s String to be printed on the terminal. +* +* Return value +* >= 0 - Number of bytes written. +* < 0 - Error. +* +*/ +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s) { + int Status; + unsigned FragLen; + unsigned Avail; + SEGGER_RTT_BUFFER_UP* pRing; + // + INIT(); + // + // Validate terminal ID. + // + if (TerminalId < (char)sizeof(_aTerminalId)) { // We only support a certain number of channels + // + // Get "to-host" ring buffer. + // + pRing = &_SEGGER_RTT.aUp[0]; + // + // Need to be able to change terminal, write data, change back. + // Compute the fixed and variable sizes. + // + FragLen = STRLEN(s); + // + // How we output depends upon the mode... + // + SEGGER_RTT_LOCK(); + Avail = _GetAvailWriteSpace(pRing); + switch (pRing->Flags & SEGGER_RTT_MODE_MASK) { + case SEGGER_RTT_MODE_NO_BLOCK_SKIP: + // + // If we are in skip mode and there is no space for the whole + // of this output, don't bother switching terminals at all. + // + if (Avail < (FragLen + 4u)) { + Status = 0; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_NO_BLOCK_TRIM: + // + // If we are in trim mode and there is not enough space for everything, + // trim the output but always include the terminal switch. If no room + // for terminal switch, skip that totally. + // + if (Avail < 4u) { + Status = -1; + } else { + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, (FragLen < (Avail - 4u)) ? FragLen : (Avail - 4u)); + _PostTerminalSwitch(pRing, _ActiveTerminal); + } + break; + case SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL: + // + // If we are in blocking mode, output everything. + // + _PostTerminalSwitch(pRing, TerminalId); + Status = (int)_WriteBlocking(pRing, s, FragLen); + _PostTerminalSwitch(pRing, _ActiveTerminal); + break; + default: + Status = -1; + break; + } + // + // Finish up. + // + SEGGER_RTT_UNLOCK(); + } else { + Status = -1; + } + return Status; +} + +#if 1 /* << EST: extra function */ +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex) { /* << EST */ + unsigned int avail; + + INIT(); + SEGGER_RTT_LOCK(); + avail = _GetAvailWriteSpace(&_SEGGER_RTT.aUp[bufferIndex]); + SEGGER_RTT_UNLOCK(); + return avail; +} +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.h new file mode 100644 index 0000000..bfe4fbf --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT.h @@ -0,0 +1,257 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT.h +Purpose : Implementation of SEGGER real-time transfer which allows + real-time communication on targets which support debugger + memory accesses while the CPU is running. +Revision: $Rev: 10533 $ +---------------------------------------------------------------------- +*/ + +#ifndef SEGGER_RTT_H +#define SEGGER_RTT_H + +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, fixed +* +********************************************************************** +*/ + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as up-buffer (T->H) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + unsigned WrOff; // Position of next item to be written by either target. + volatile unsigned RdOff; // Position of next item to be read by host. Must be volatile since it may be modified by host. + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_UP; + +// +// Description for a circular buffer (also called "ring buffer") +// which is used as down-buffer (H->T) +// +typedef struct { + const char* sName; // Optional name. Standard names so far are: "Terminal", "SysView", "J-Scope_t4i4" + char* pBuffer; // Pointer to start of buffer + unsigned SizeOfBuffer; // Buffer size in bytes. Note that one byte is lost, as this implementation does not fill up the buffer in order to avoid the problem of being unable to distinguish between full and empty. + volatile unsigned WrOff; // Position of next item to be written by host. Must be volatile since it may be modified by host. + unsigned RdOff; // Position of next item to be read by target (down-buffer). + unsigned Flags; // Contains configuration flags +} SEGGER_RTT_BUFFER_DOWN; + +// +// RTT control block which describes the number of buffers available +// as well as the configuration for each buffer +// +// +typedef struct { + char acID[16]; // Initialized to "SEGGER RTT" + int MaxNumUpBuffers; // Initialized to SEGGER_RTT_MAX_NUM_UP_BUFFERS (type. 2) + int MaxNumDownBuffers; // Initialized to SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (type. 2) + SEGGER_RTT_BUFFER_UP aUp[SEGGER_RTT_MAX_NUM_UP_BUFFERS]; // Up buffers, transferring information up from target via debug probe to host + SEGGER_RTT_BUFFER_DOWN aDown[SEGGER_RTT_MAX_NUM_DOWN_BUFFERS]; // Down buffers, transferring information down from host via debug probe to target +} SEGGER_RTT_CB; + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ +extern SEGGER_RTT_CB _SEGGER_RTT; + +/********************************************************************* +* +* RTT API functions +* +********************************************************************** +*/ +#ifdef __cplusplus + extern "C" { +#endif +int SEGGER_RTT_AllocDownBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_AllocUpBuffer (const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigUpBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_ConfigDownBuffer (unsigned BufferIndex, const char* sName, void* pBuffer, unsigned BufferSize, unsigned Flags); +int SEGGER_RTT_GetKey (void); +unsigned SEGGER_RTT_HasData (unsigned BufferIndex); +int SEGGER_RTT_HasKey (void); +unsigned SEGGER_RTT_HasDataUp (unsigned BufferIndex); +void SEGGER_RTT_Init (void); +unsigned SEGGER_RTT_Read (unsigned BufferIndex, void* pBuffer, unsigned BufferSize); +unsigned SEGGER_RTT_ReadNoLock (unsigned BufferIndex, void* pData, unsigned BufferSize); +int SEGGER_RTT_SetNameDownBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetNameUpBuffer (unsigned BufferIndex, const char* sName); +int SEGGER_RTT_SetFlagsDownBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_SetFlagsUpBuffer (unsigned BufferIndex, unsigned Flags); +int SEGGER_RTT_WaitKey (void); +unsigned SEGGER_RTT_Write (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteSkipNoLock (unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_WriteString (unsigned BufferIndex, const char* s); +void SEGGER_RTT_WriteWithOverwriteNoLock(unsigned BufferIndex, const void* pBuffer, unsigned NumBytes); +unsigned SEGGER_RTT_PutChar (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkip (unsigned BufferIndex, char c); +unsigned SEGGER_RTT_PutCharSkipNoLock (unsigned BufferIndex, char c); +unsigned int SEGGER_RTT_GetUpBufferFreeSize(unsigned int bufferIndex); /* << EST */ +// +// Function macro for performance optimization +// +#define SEGGER_RTT_HASDATA(n) (_SEGGER_RTT.aDown[n].WrOff - _SEGGER_RTT.aDown[n].RdOff) + +/********************************************************************* +* +* RTT "Terminal" API functions +* +********************************************************************** +*/ +int SEGGER_RTT_SetTerminal (char TerminalId); +int SEGGER_RTT_TerminalOut (char TerminalId, const char* s); + +/********************************************************************* +* +* RTT printf functions (require SEGGER_RTT_printf.c) +* +********************************************************************** +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...); + +int SEGGER_printf(const char * sFormat, ...); /* << EST */ + +#ifdef __cplusplus + } +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +// +// Operating modes. Define behavior if buffer is full (not enough space for entire message) +// +#define SEGGER_RTT_MODE_NO_BLOCK_SKIP (0U) // Skip. Do not block, output nothing. (Default) +#define SEGGER_RTT_MODE_NO_BLOCK_TRIM (1U) // Trim: Do not block, output as much as fits. +#define SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL (2U) // Block: Wait until there is space in the buffer. +#define SEGGER_RTT_MODE_MASK (3U) + +// +// Control sequences, based on ANSI. +// Can be used to control color, and clear the screen +// +#define RTT_CTRL_RESET "" // Reset to default colors +#define RTT_CTRL_CLEAR "" // Clear screen, reposition cursor to top left + +#define RTT_CTRL_TEXT_BLACK "" +#define RTT_CTRL_TEXT_RED "" +#define RTT_CTRL_TEXT_GREEN "" +#define RTT_CTRL_TEXT_YELLOW "" +#define RTT_CTRL_TEXT_BLUE "" +#define RTT_CTRL_TEXT_MAGENTA "" +#define RTT_CTRL_TEXT_CYAN "" +#define RTT_CTRL_TEXT_WHITE "" + +#define RTT_CTRL_TEXT_BRIGHT_BLACK "" +#define RTT_CTRL_TEXT_BRIGHT_RED "" +#define RTT_CTRL_TEXT_BRIGHT_GREEN "" +#define RTT_CTRL_TEXT_BRIGHT_YELLOW "" +#define RTT_CTRL_TEXT_BRIGHT_BLUE "" +#define RTT_CTRL_TEXT_BRIGHT_MAGENTA "" +#define RTT_CTRL_TEXT_BRIGHT_CYAN "" +#define RTT_CTRL_TEXT_BRIGHT_WHITE "" + +#define RTT_CTRL_BG_BLACK "" +#define RTT_CTRL_BG_RED "" +#define RTT_CTRL_BG_GREEN "" +#define RTT_CTRL_BG_YELLOW "" +#define RTT_CTRL_BG_BLUE "" +#define RTT_CTRL_BG_MAGENTA "" +#define RTT_CTRL_BG_CYAN "" +#define RTT_CTRL_BG_WHITE "" + +#define RTT_CTRL_BG_BRIGHT_BLACK "" +#define RTT_CTRL_BG_BRIGHT_RED "" +#define RTT_CTRL_BG_BRIGHT_GREEN "" +#define RTT_CTRL_BG_BRIGHT_YELLOW "" +#define RTT_CTRL_BG_BRIGHT_BLUE "" +#define RTT_CTRL_BG_BRIGHT_MAGENTA "" +#define RTT_CTRL_BG_BRIGHT_CYAN "" +#define RTT_CTRL_BG_BRIGHT_WHITE "" + + +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_Conf.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_Conf.h new file mode 100644 index 0000000..c7c610a --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_Conf.h @@ -0,0 +1,355 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_Conf.h +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support + debugger memory accesses while the CPU is running. +Revision: $Rev: 9599 $ + +*/ + +#ifndef SEGGER_RTT_CONF_H +#define SEGGER_RTT_CONF_H + +#ifdef __IAR_SYSTEMS_ICC__ + #include +#endif + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ +/* << EST: Additional setting to check for FreeRTOS: need to use FreeRTOS with proper BASEPRI mask to create critical sections */ +#include "MCUC1.h" /* SDK and API used */ +#include "RTT1config.h" /* configuration */ + +#if MCUC1_CONFIG_SDK_USE_FREERTOS + #include "portmacro.h" /* include FreeRTOS port header file for critical section handling */ +#endif + +/* Channel 0 settings from properties */ /* << EST */ +#define SEGGER_RTT_CHANNEL_0_ENABLED (1) /* 1: initialize channel; 0: do not initialize channel */ +#define SEGGER_RTT_CHANNEL_0_NAME "Terminal" +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) +#define SEGGER_RTT_CHANNEL_0_BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) +#define SEGGER_RTT_CHANNEL_0_MODE_UP SEGGER_RTT_MODE_NO_BLOCK_SKIP +#define SEGGER_RTT_CHANNEL_0_MODE_DOWN SEGGER_RTT_MODE_NO_BLOCK_SKIP + +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (1) // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (1) // Max. number of down-buffers (H->T) available on this target (Default: 2) + +#define BUFFER_SIZE_UP (RTT1_CONFIG_RTT_BUFFER_SIZE_UP) // Size of the buffer for terminal output of target, up to host (Default: 1k) +#define BUFFER_SIZE_DOWN (RTT1_CONFIG_RTT_BUFFER_SIZE_DOWN) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) + +#define SEGGER_RTT_PRINTF_BUFFER_SIZE (RTT1_CONFIG_RTT_BUFFER_SIZE_PRINTF) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) +#define SEGGER_RTT_MODE_DEFAULT SEGGER_RTT_MODE_NO_BLOCK_SKIP // Mode for pre-initialized terminal channel (buffer 0) + +/********************************************************************* +* +* RTT memcpy configuration +* +* memcpy() is good for large amounts of data, +* but the overhead is big for small amounts, which are usually stored via RTT. +* With SEGGER_RTT_MEMCPY_USE_BYTELOOP a simple byte loop can be used instead. +* +* SEGGER_RTT_MEMCPY() can be used to replace standard memcpy() in RTT functions. +* This is may be required with memory access restrictions, +* such as on Cortex-A devices with MMU. +*/ +#define SEGGER_RTT_MEMCPY_USE_BYTELOOP 0 // 0: Use memcpy/SEGGER_RTT_MEMCPY, 1: Use a simple byte-loop +// +// Example definition of SEGGER_RTT_MEMCPY to external memcpy with GCC toolchains and Cortex-A targets +// +//#if ((defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__)) && (defined (__ARM_ARCH_7A__)) +// #define SEGGER_RTT_MEMCPY(pDest, pSrc, NumBytes) SEGGER_memcpy((pDest), (pSrc), (NumBytes)) +//#endif + +// +// Target is not allowed to perform other RTT operations while string still has not been stored completely. +// Otherwise we would probably end up with a mixed string in the buffer. +// If using RTT from within interrupts, multiple tasks or multi processors, define the SEGGER_RTT_LOCK() and SEGGER_RTT_UNLOCK() function here. +// +// SEGGER_RTT_MAX_INTERRUPT_PRIORITY can be used in the sample lock routines on Cortex-M3/4. +// Make sure to mask all interrupts which can send RTT data, i.e. generate SystemView events, or cause task switches. +// When high-priority interrupts must not be masked while sending RTT data, SEGGER_RTT_MAX_INTERRUPT_PRIORITY needs to be adjusted accordingly. +// (Higher priority = lower priority number) +// Default value for embOS: 128u +// Default configuration in FreeRTOS: configMAX_SYSCALL_INTERRUPT_PRIORITY: ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +// In case of doubt mask all interrupts: 1 << (8 - BASEPRI_PRIO_BITS) i.e. 1 << 5 when 3 bits are implemented in NVIC +// or define SEGGER_RTT_LOCK() to completely disable interrupts. +// + +#define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) // Interrupt priority to lock on SEGGER_RTT_LOCK on Cortex-M3/4 (Default: 0x20) + +/********************************************************************* +* +* RTT lock configuration for SEGGER Embedded Studio, +* Rowley CrossStudio and GCC +*/ +#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) + #ifdef __ARM_ARCH_6M__ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, primask \n\t" \ + "mov r1, $1 \n\t" \ + "msr primask, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr primask, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) + /* >> EST */ + #if SEGGER_RTT_FREERTOS_PRESENT + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY configMAX_SYSCALL_INTERRUPT_PRIORITY /* Interrupts at this level and below will be blocked (valid values 1-15) */ + #else + #define SEGGER_RTT_LOCK_INTERRUPT_LEVEL 3 /* Interrupts at this level and below will be blocked (valid values 1-15 for Kinetis) */ + #define SEGGER_RTT_PRIO_BITS 4 /* NXP Kinetis M4(F) has 4 interrupt priority bits */ + #define SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY (SEGGER_RTT_LOCK_INTERRUPT_LEVEL<<(8-SEGGER_RTT_PRIO_BITS)) + #endif + /* >> EST */ + #define SEGGER_RTT_LOCK() { \ + /*lint -save -e529 Symbol 'LockState' not subsequently referenced */ \ + unsigned int LockState; \ + __asm volatile ("mrs %0, basepri \n\t" \ + "mov r1, %1 \n\t" \ + "msr basepri, r1 \n\t" \ + : "=r" (LockState) \ + : "i"(SEGGER_RTT_BLOCKED_INTERRUPT_PRIORITY) /* input */\ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("msr basepri, %0 \n\t" \ + : \ + : "r" (LockState) \ + : \ + ); \ + /*lint -restore */ \ + } + + #elif defined(__ARM_ARCH_7A__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + __asm volatile ("mrs r1, CPSR \n\t" \ + "mov %0, r1 \n\t" \ + "orr r1, r1, #0xC0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : "=r" (LockState) \ + : \ + : "r1" \ + ); + + #define SEGGER_RTT_UNLOCK() __asm volatile ("mov r0, %0 \n\t" \ + "mrs r1, CPSR \n\t" \ + "bic r1, r1, #0xC0 \n\t" \ + "and r0, r0, #0xC0 \n\t" \ + "orr r1, r1, r0 \n\t" \ + "msr CPSR_c, r1 \n\t" \ + : \ + : "r" (LockState) \ + : "r0", "r1" \ + ); \ + } + #else + #define SEGGER_RTT_LOCK() + #define SEGGER_RTT_UNLOCK() + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR EWARM +*/ +#ifdef __ICCARM__ + #if (defined (__ARM6M__) && (__CORE__ == __ARM6M__)) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif ((defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) || (defined (__ARM7M__) && (__CORE__ == __ARM7M__))) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_BASEPRI(); \ + __set_BASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() __set_BASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RX +*/ +#ifdef __ICCRX__ + #define SEGGER_RTT_LOCK() { \ + unsigned long LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for IAR RL78 +*/ +#ifdef __ICCRL78__ + #define SEGGER_RTT_LOCK() { \ + __istate_t LockState; \ + LockState = __get_interrupt_state(); \ + __disable_interrupt(); + + #define SEGGER_RTT_UNLOCK() __set_interrupt_state(LockState); \ + } +#endif + +/********************************************************************* +* +* RTT lock configuration for KEIL ARM +*/ +#ifdef __CC_ARM + #if (defined __TARGET_ARCH_6S_M) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char PRIMASK __asm( "primask"); \ + LockState = PRIMASK; \ + PRIMASK = 1u; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() PRIMASK = LockState; \ + __schedule_barrier(); \ + } + #elif (defined(__TARGET_ARCH_7_M) || defined(__TARGET_ARCH_7E_M)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + register unsigned char BASEPRI __asm( "basepri"); \ + LockState = BASEPRI; \ + BASEPRI = SEGGER_RTT_MAX_INTERRUPT_PRIORITY; \ + __schedule_barrier(); + + #define SEGGER_RTT_UNLOCK() BASEPRI = LockState; \ + __schedule_barrier(); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration for TI ARM +*/ +#ifdef __TI_ARM__ + #if defined (__TI_ARM_V6M0__) + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = __get_PRIMASK(); \ + __set_PRIMASK(1); + + #define SEGGER_RTT_UNLOCK() __set_PRIMASK(LockState); \ + } + #elif (defined (__TI_ARM_V7M3__) || defined (__TI_ARM_V7M4__)) + #ifndef SEGGER_RTT_MAX_INTERRUPT_PRIORITY + #define SEGGER_RTT_MAX_INTERRUPT_PRIORITY (0x20) + #endif + #define SEGGER_RTT_LOCK() { \ + unsigned int LockState; \ + LockState = OS_GetBASEPRI(); \ + OS_SetBASEPRI(SEGGER_RTT_MAX_INTERRUPT_PRIORITY); + + #define SEGGER_RTT_UNLOCK() OS_SetBASEPRI(LockState); \ + } + #endif +#endif + +/********************************************************************* +* +* RTT lock configuration fallback +*/ +#ifndef SEGGER_RTT_LOCK + #define SEGGER_RTT_LOCK() // Lock RTT (nestable) (i.e. disable interrupts) +#endif + +#ifndef SEGGER_RTT_UNLOCK + #define SEGGER_RTT_UNLOCK() // Unlock RTT (nestable) (i.e. enable previous interrupt lock state) +#endif + +#endif +/*************************** End of file ****************************/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_printf.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_printf.c new file mode 100644 index 0000000..bc2f57f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SEGGER_RTT_printf.c @@ -0,0 +1,563 @@ +/********************************************************************* +* SEGGER Microcontroller GmbH * +* The Embedded Experts * +********************************************************************** +* * +* (c) 1995 - 2018 SEGGER Microcontroller GmbH * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* SEGGER RTT * Real Time Transfer for embedded targets * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* SEGGER strongly recommends to not make any changes * +* to or modify the source code of this software in order to stay * +* compatible with the RTT protocol and J-Link. * +* * +* Redistribution and use in source and binary forms, with or * +* without modification, are permitted provided that the following * +* conditions are met: * +* * +* o Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* o Redistributions in binary form must reproduce the above * +* copyright notice, this list of conditions and the following * +* disclaimer in the documentation and/or other materials provided * +* with the distribution. * +* * +* o Neither the name of SEGGER Microcontroller GmbH * +* nor the names of its contributors may be used to endorse or * +* promote products derived from this software without specific * +* prior written permission. * +* * +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * +* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * +* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * +* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * +* DISCLAIMED. IN NO EVENT SHALL SEGGER Microcontroller BE LIABLE FOR * +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * +* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * +* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * +* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * +* DAMAGE. * +* * +********************************************************************** +* * +* RTT version: 6.32b * +* * +********************************************************************** +---------------------------END-OF-HEADER------------------------------ +File : SEGGER_RTT_printf.c +Purpose : Replacement for printf to write formatted data via RTT +Revision: $Rev: 9599 $ +---------------------------------------------------------------------- +*/ +#include "SEGGER_RTT.h" +#include "SEGGER_RTT_Conf.h" + +/********************************************************************* +* +* Defines, configurable +* +********************************************************************** +*/ + +#ifndef SEGGER_RTT_PRINTF_BUFFER_SIZE + #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64) +#endif + +#include +#include + + +#define FORMAT_FLAG_LEFT_JUSTIFY (1u << 0) +#define FORMAT_FLAG_PAD_ZERO (1u << 1) +#define FORMAT_FLAG_PRINT_SIGN (1u << 2) +#define FORMAT_FLAG_ALTERNATE (1u << 3) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + unsigned BufferSize; + unsigned Cnt; + + int ReturnValue; + + unsigned RTTBufferIndex; +} SEGGER_RTT_PRINTF_DESC; + +/********************************************************************* +* +* Function prototypes +* +********************************************************************** +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _StoreChar +*/ +static void _StoreChar(SEGGER_RTT_PRINTF_DESC * p, char c) { + unsigned Cnt; + + Cnt = p->Cnt; + if ((Cnt + 1u) <= p->BufferSize) { + *(p->pBuffer + Cnt) = c; + p->Cnt = Cnt + 1u; + p->ReturnValue++; + } + // + // Write part of string, when the buffer is full + // + if (p->Cnt == p->BufferSize) { + if (SEGGER_RTT_Write(p->RTTBufferIndex, p->pBuffer, p->Cnt) != p->Cnt) { + p->ReturnValue = -1; + } else { + p->Cnt = 0u; + } + } +} + +/********************************************************************* +* +* _PrintUnsigned +*/ +static void _PrintUnsigned(SEGGER_RTT_PRINTF_DESC * pBufferDesc, unsigned v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + static const char _aV2C[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + unsigned Div; + unsigned Digit; + unsigned Number; + unsigned Width; + char c; + + Number = v; + Digit = 1u; + // + // Get actual field width + // + Width = 1u; + while (Number >= Base) { + Number = (Number / Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + // + // Print leading chars if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) { + if (FieldWidth != 0u) { + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && (NumDigits == 0u)) { + c = '0'; + } else { + c = ' '; + } + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, c); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Compute Digit. + // Loop until Digit has the value of the highest digit required. + // Example: If the output is 345 (Base 10), loop 2 times until Digit is 100. + // + while (1) { + if (NumDigits > 1u) { // User specified a min number of digits to print? => Make sure we loop at least that often, before checking anything else (> 1 check avoids problems with NumDigits being signed / unsigned) + NumDigits--; + } else { + Div = v / Digit; + if (Div < Base) { // Is our divider big enough to extract the highest digit from value? => Done + break; + } + } + Digit *= Base; + } + // + // Output digits + // + do { + Div = v / Digit; + v -= Div * Digit; + _StoreChar(pBufferDesc, _aV2C[Div]); + if (pBufferDesc->ReturnValue < 0) { + break; + } + Digit /= Base; + } while (Digit); + // + // Print trailing spaces if necessary + // + if ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == FORMAT_FLAG_LEFT_JUSTIFY) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + } +} + +/********************************************************************* +* +* _PrintInt +*/ +static void _PrintInt(SEGGER_RTT_PRINTF_DESC * pBufferDesc, int v, unsigned Base, unsigned NumDigits, unsigned FieldWidth, unsigned FormatFlags) { + unsigned Width; + int Number; + + Number = (v < 0) ? -v : v; + + // + // Get actual field width + // + Width = 1u; + while (Number >= (int)Base) { + Number = (Number / (int)Base); + Width++; + } + if (NumDigits > Width) { + Width = NumDigits; + } + if ((FieldWidth > 0u) && ((v < 0) || ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN))) { + FieldWidth--; + } + + // + // Print leading spaces if necessary + // + if ((((FormatFlags & FORMAT_FLAG_PAD_ZERO) == 0u) || (NumDigits != 0u)) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, ' '); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + // + // Print sign if necessary + // + if (pBufferDesc->ReturnValue >= 0) { + if (v < 0) { + v = -v; + _StoreChar(pBufferDesc, '-'); + } else if ((FormatFlags & FORMAT_FLAG_PRINT_SIGN) == FORMAT_FLAG_PRINT_SIGN) { + _StoreChar(pBufferDesc, '+'); + } else { + + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print leading zeros if necessary + // + if (((FormatFlags & FORMAT_FLAG_PAD_ZERO) == FORMAT_FLAG_PAD_ZERO) && ((FormatFlags & FORMAT_FLAG_LEFT_JUSTIFY) == 0u) && (NumDigits == 0u)) { + if (FieldWidth != 0u) { + while ((FieldWidth != 0u) && (Width < FieldWidth)) { + FieldWidth--; + _StoreChar(pBufferDesc, '0'); + if (pBufferDesc->ReturnValue < 0) { + break; + } + } + } + } + if (pBufferDesc->ReturnValue >= 0) { + // + // Print number without sign + // + _PrintUnsigned(pBufferDesc, (unsigned)v, Base, NumDigits, FieldWidth, FormatFlags); + } + } + } +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* SEGGER_RTT_vprintf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string +* pParamList Pointer to the list of arguments for the format string +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +*/ +int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList) { + char c; + SEGGER_RTT_PRINTF_DESC BufferDesc; + int v; + unsigned NumDigits; + unsigned FormatFlags; + unsigned FieldWidth; + char acBuffer[SEGGER_RTT_PRINTF_BUFFER_SIZE]; + + BufferDesc.pBuffer = acBuffer; + BufferDesc.BufferSize = SEGGER_RTT_PRINTF_BUFFER_SIZE; + BufferDesc.Cnt = 0u; + BufferDesc.RTTBufferIndex = BufferIndex; + BufferDesc.ReturnValue = 0; + + do { + c = *sFormat; + sFormat++; + if (c == 0u) { + break; + } + if (c == '%') { + // + // Filter out flags + // + FormatFlags = 0u; + v = 1; + do { + c = *sFormat; + switch (c) { + case '-': FormatFlags |= FORMAT_FLAG_LEFT_JUSTIFY; sFormat++; break; + case '0': FormatFlags |= FORMAT_FLAG_PAD_ZERO; sFormat++; break; + case '+': FormatFlags |= FORMAT_FLAG_PRINT_SIGN; sFormat++; break; + case '#': FormatFlags |= FORMAT_FLAG_ALTERNATE; sFormat++; break; + default: v = 0; break; + } + } while (v); + // + // filter out field with + // + FieldWidth = 0u; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + FieldWidth = (FieldWidth * 10u) + ((unsigned)c - '0'); + } while (1); + + // + // Filter out precision (number of digits to display) + // + NumDigits = 0u; + c = *sFormat; + if (c == '.') { + sFormat++; + do { + c = *sFormat; + if ((c < '0') || (c > '9')) { + break; + } + sFormat++; + NumDigits = NumDigits * 10u + ((unsigned)c - '0'); + } while (1); + } + // + // Filter out length modifier + // + c = *sFormat; + do { + if ((c == 'l') || (c == 'h')) { + sFormat++; + c = *sFormat; + } else { + break; + } + } while (1); + // + // Handle specifiers + // + switch (c) { + case 'c': { + char c0; + v = va_arg(*pParamList, int); + c0 = (char)v; + _StoreChar(&BufferDesc, c0); + break; + } + case 'd': + v = va_arg(*pParamList, int); + _PrintInt(&BufferDesc, v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'u': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 10u, NumDigits, FieldWidth, FormatFlags); + break; + case 'x': + case 'X': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, NumDigits, FieldWidth, FormatFlags); + break; + case 's': + { + const char * s = va_arg(*pParamList, const char *); + do { + c = *s; + s++; + if (c == '\0') { + break; + } + _StoreChar(&BufferDesc, c); + } while (BufferDesc.ReturnValue >= 0); + } + break; + case 'p': + v = va_arg(*pParamList, int); + _PrintUnsigned(&BufferDesc, (unsigned)v, 16u, 8u, 8u, 0u); + break; + case '%': + _StoreChar(&BufferDesc, '%'); + break; + default: + break; + } + sFormat++; + } else { + _StoreChar(&BufferDesc, c); + } + } while (BufferDesc.ReturnValue >= 0); + + if (BufferDesc.ReturnValue > 0) { + // + // Write remaining data, if any + // + if (BufferDesc.Cnt != 0u) { + SEGGER_RTT_Write(BufferIndex, acBuffer, BufferDesc.Cnt); + } +#if 0 + BufferDesc.ReturnValue += (int)BufferDesc.Cnt; +#else /* << EST: Do not count the characters twice! */ + BufferDesc.ReturnValue = (int)BufferDesc.Cnt; +#endif + } + return BufferDesc.ReturnValue; +} + +/********************************************************************* +* +* SEGGER_RTT_printf +* +* Function description +* Stores a formatted string in SEGGER RTT control block. +* This data is read by the host. +* +* Parameters +* BufferIndex Index of "Up"-buffer to be used. (e.g. 0 for "Terminal") +* sFormat Pointer to format string, followed by the arguments for conversion +* +* Return values +* >= 0: Number of bytes which have been stored in the "Up"-buffer. +* < 0: Error +* +* Notes +* (1) Conversion specifications have following syntax: +* %[flags][FieldWidth][.Precision]ConversionSpecifier +* (2) Supported flags: +* -: Left justify within the field width +* +: Always print sign extension for signed conversions +* 0: Pad with 0 instead of spaces. Ignored when using '-'-flag or precision +* Supported conversion specifiers: +* c: Print the argument as one char +* d: Print the argument as a signed integer +* u: Print the argument as an unsigned integer +* x: Print the argument as an hexadecimal integer +* s: Print the string pointed to by the argument +* p: Print the argument as an 8-digit hexadecimal integer. (Argument shall be a pointer to void.) +*/ +int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { + int r; + va_list ParamList; + + va_start(ParamList, sFormat); + r = SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); + va_end(ParamList); + return r; +} + +#if 0 /* << EST extension to support extra format characters like %f */ +#include "McuXFormat.h" +#include "McuWait.h" + +int SEGGER_printf(const char * sFormat, ...) { + static char buffer[256]; /* NOT reentrant! */ + va_list args; + int res; + unsigned int avail; + + va_start(args, sFormat); + res = xsnprintf(buffer, sizeof(buffer), sFormat, args); + va_end(args); + if (res > 0) { + int retry = 5; + + do { + /* res is the number of characters written */ + avail = SEGGER_RTT_GetUpBufferFreeSize(0); + if (avail>res) { + break; /* enough space available */ + } else { + McuWait_Waitms(50); + retry--; + } + } while(retry>0); + return SEGGER_RTT_printf(0, "%s", buffer); + } + return -1; /* failed */ +} +#else +int SEGGER_printf(const char * sFormat, ...) { + va_list ParamList; + int res; + + va_start(ParamList, sFormat); + res = SEGGER_RTT_vprintf(0, sFormat, &ParamList); + va_end(ParamList); + return res; +} +#endif + +/*************************** End of file ****************************/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.c new file mode 100644 index 0000000..52efcde --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.c @@ -0,0 +1,124 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_FWD.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_FWD +** Pin for I/O : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/I2S0_MCLK +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_FWD_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_FWD.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_FWD_module SW_FWD module documentation +** @{ +*/ + +/* MODULE SW_FWD. */ + +#include "SW_FWD.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : SW_FWD_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool SW_FWD_GetVal(void) + +** This method is implemented as a macro. See SW_FWD.h file. ** +*/ + +/* END SW_FWD. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.h new file mode 100644 index 0000000..4083812 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_FWD.h @@ -0,0 +1,136 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_FWD.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_FWD +** Pin for I/O : CMP0_IN0/PTC6/LLWU_P10/SPI0_SOUT/PDB0_EXTRG/I2S0_RX_BCLK/I2S0_MCLK +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_FWD_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_FWD.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_FWD_module SW_FWD module documentation +** @{ +*/ + +#ifndef __SW_FWD_H +#define __SW_FWD_H + +/* MODULE SW_FWD. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd2.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : SW_FWD_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define SW_FWD_GetVal() (BitIoLdd2_GetVal(BitIoLdd2_DeviceData)) + +/* END SW_FWD. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __SW_FWD_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.c new file mode 100644 index 0000000..6f30281 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.c @@ -0,0 +1,124 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_PEELER.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 12:37, # CodeGen: 10 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_PEELER +** Pin for I/O : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/CMP0_OUT +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_PEELER_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_PEELER.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_PEELER_module SW_PEELER module documentation +** @{ +*/ + +/* MODULE SW_PEELER. */ + +#include "SW_PEELER.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : SW_PEELER_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool SW_PEELER_GetVal(void) + +** This method is implemented as a macro. See SW_PEELER.h file. ** +*/ + +/* END SW_PEELER. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.h new file mode 100644 index 0000000..0d3df08 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_PEELER.h @@ -0,0 +1,136 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_PEELER.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 12:37, # CodeGen: 10 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_PEELER +** Pin for I/O : PTC5/LLWU_P9/SPI0_SCK/LPTMR0_ALT2/I2S0_RXD0/CMP0_OUT +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_PEELER_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_PEELER.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_PEELER_module SW_PEELER module documentation +** @{ +*/ + +#ifndef __SW_PEELER_H +#define __SW_PEELER_H + +/* MODULE SW_PEELER. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd4.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : SW_PEELER_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define SW_PEELER_GetVal() (BitIoLdd4_GetVal(BitIoLdd4_DeviceData)) + +/* END SW_PEELER. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __SW_PEELER_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.c new file mode 100644 index 0000000..f32e820 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.c @@ -0,0 +1,124 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_REV.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_REV +** Pin for I/O : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_REV_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_REV.c +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_REV_module SW_REV module documentation +** @{ +*/ + +/* MODULE SW_REV. */ + +#include "SW_REV.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** =================================================================== +** Method : SW_REV_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +/* +bool SW_REV_GetVal(void) + +** This method is implemented as a macro. See SW_REV.h file. ** +*/ + +/* END SW_REV. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.h new file mode 100644 index 0000000..0ff66be --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/SW_REV.h @@ -0,0 +1,136 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : SW_REV.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : BitIO +** Version : Component 02.086, Driver 01.00, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +** Settings : +** Component name : SW_REV +** Pin for I/O : CMP0_IN1/PTC7/SPI0_SIN/USB_SOF_OUT/I2S0_RX_FS +** Pin signal : +** BitIO_LDD : BitIO_LDD +** Direction : Input +** Initialization : +** Init. direction : Input +** Init. value : 0 +** Safe mode : no +** Optimization for : speed +** Contents : +** GetVal - bool SW_REV_GetVal(void); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file SW_REV.h +** @version 01.00 +** @brief +** This component "BitIO" implements an one-bit input/output. +** It uses one bit/pin of a port. +** Note: This component is set to work in Input direction only. +** Methods of this component are mostly implemented as a macros +** (if supported by target language and compiler). +*/ +/*! +** @addtogroup SW_REV_module SW_REV module documentation +** @{ +*/ + +#ifndef __SW_REV_H +#define __SW_REV_H + +/* MODULE SW_REV. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ +#include "BitIoLdd3.h" + +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/* +** =================================================================== +** Method : SW_REV_GetVal (component BitIO) +** Description : +** This method returns an input value. +** a) direction = Input : reads the input value from the +** pin and returns it +** b) direction = Output : returns the last written value +** Note: This component is set to work in Input direction only. +** Parameters : None +** Returns : +** --- - Input value. Possible values: +** FALSE - logical "0" (Low level) +** TRUE - logical "1" (High level) + +** =================================================================== +*/ +#define SW_REV_GetVal() (BitIoLdd3_GetVal(BitIoLdd3_DeviceData)) + +/* END SW_REV. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __SW_REV_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.c new file mode 100644 index 0000000..c66dbb2 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.c @@ -0,0 +1,504 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU1.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : uint16_t +** Input clock source : Internal +** Counter frequency : Auto select +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 1 kHz +** Interrupt : Disabled +** Channel list : 2 +** Channel 0 : +** Mode : Compare +** Compare : FTM0_C0V +** Offset : 0 ms +** Output on compare : Clear +** Output on overrun : Set +** Initial state : High +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Interrupt : Disabled +** Channel 1 : +** Mode : Compare +** Compare : FTM0_C2V +** Offset : 0 ms +** Output on compare : Clear +** Output on overrun : Set +** Initial state : High +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Interrupt : Disabled +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Disabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); +** GetPeriodTicks - LDD_TError TU1_GetPeriodTicks(LDD_TDeviceData *DeviceDataPtr, TU1_TValueType... +** GetCounterValue - TU1_TValueType TU1_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); +** SetOffsetTicks - LDD_TError TU1_SetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** GetOffsetTicks - LDD_TError TU1_GetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** SelectOutputAction - LDD_TError TU1_SelectOutputAction(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU1.c +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU1_module TU1 module documentation +** @{ +*/ + +/* MODULE TU1. */ + +#include "TU1.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* List of channels used by component */ +static const uint8_t ChannelDevice[TU1_NUMBER_OF_CHANNELS] = {0x00U,0x02U}; + +/* Table of channels mode / 0 - compare mode, 1 - capture mode */ +static const uint8_t ChannelMode[TU1_NUMBER_OF_CHANNELS] = {0x00U,0x00U}; + + +typedef struct { + uint8_t InitCntr; /* Number of initialization */ + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} TU1_TDeviceData; + +typedef TU1_TDeviceData *TU1_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static TU1_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; + +#define AVAILABLE_PIN_MASK (LDD_TPinMask)(TU1_CHANNEL_0_PIN | TU1_CHANNEL_1_PIN) +#define LAST_CHANNEL 0x01U + +/* Internal method prototypes */ +/* +** =================================================================== +** Method : TU1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr) +{ + TU1_TDeviceData *DeviceDataPrv; + + if (PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID] == NULL) { + /* Allocate device structure */ + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->InitCntr = 1U; /* First initialization */ + } + else { + /* Memory is already allocated */ + DeviceDataPrv = (TU1_TDeviceDataPtr) PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID]; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + DeviceDataPrv->InitCntr++; /* Increment counter of initialization */ + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ + } + /* SIM_SCGC6: FTM0=1 */ + SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; + /* FTM0_MODE: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FAULTIE=0,FAULTM=0,CAPTEST=0,PWMSYNC=0,WPDIS=1,INIT=0,FTMEN=0 */ + FTM0_MODE = (FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK); /* Set up mode register */ + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=0,PS=0 */ + FTM0_SC = (FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00)); /* Clear status and control register */ + /* FTM0_CNTIN: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,INIT=0 */ + FTM0_CNTIN = FTM_CNTIN_INIT(0x00); /* Clear counter initial register */ + /* FTM0_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ + FTM0_CNT = FTM_CNT_COUNT(0x00); /* Reset counter register */ + /* FTM0_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C0SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C1SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C2SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C2SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C3SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C3SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C4SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C4SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C5SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C5SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C6SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C6SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_C7SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM0_C7SC = 0x00U; /* Clear channel status and control register */ + /* FTM0_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0x61A7 */ + FTM0_MOD = FTM_MOD_MOD(0x61A7); /* Set up modulo register */ + /* FTM0_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=0,??=0,DMA=0 */ + FTM0_C0SC = (FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK); /* Set up channel status and control register */ + /* FTM0_C0V: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,VAL=0 */ + FTM0_C0V = FTM_CnV_VAL(0x00); /* Set up channel value register */ + /* FTM0_C2SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=0,??=0,DMA=0 */ + FTM0_C2SC = (FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK); /* Set up channel status and control register */ + /* FTM0_C2V: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,VAL=0 */ + FTM0_C2V = FTM_CnV_VAL(0x00); /* Set up channel value register */ + /* FTM0_OUTINIT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CH7OI=0,CH6OI=0,CH5OI=0,CH4OI=0,CH3OI=0,CH2OI=1,CH1OI=0,CH0OI=1 */ + FTM0_OUTINIT = (FTM_OUTINIT_CH2OI_MASK | FTM_OUTINIT_CH0OI_MASK); /* Set up Initial State for Channel Output register */ + /* FTM0_MODE: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FAULTIE=0,FAULTM=0,CAPTEST=0,PWMSYNC=0,WPDIS=1,INIT=1,FTMEN=0 */ + FTM0_MODE = (FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK | FTM_MODE_INIT_MASK); /* Initialize the Output Channels */ + /* PORTC_PCR1: ISF=0,MUX=4 */ + PORTC_PCR1 = (uint32_t)((PORTC_PCR1 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x03) + )) | (uint32_t)( + PORT_PCR_MUX(0x04) + )); + /* PORTC_PCR3: ISF=0,MUX=4 */ + PORTC_PCR3 = (uint32_t)((PORTC_PCR3 & (uint32_t)~(uint32_t)( + PORT_PCR_ISF_MASK | + PORT_PCR_MUX(0x03) + )) | (uint32_t)( + PORT_PCR_MUX(0x04) + )); + /* FTM0_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=1,PS=0 */ + FTM0_SC = (FTM_SC_CLKS(0x01) | FTM_SC_PS(0x00)); /* Set up status and control register */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU1_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : TU1_GetPeriodTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the number of counter ticks before re-initialization. +** See also method [SetPeriodTicks]. This method is available +** only if the property ["Counter restart"] is switched to +** 'on-match' value. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** TicksPtr - Pointer to return value of the +** number of counter ticks before +** re-initialization +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_GetPeriodTicks(LDD_TDeviceData *DeviceDataPtr, TU1_TValueType *TicksPtr) +{ + uint16_t tmp; + + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + tmp = (uint16_t)(FTM_PDD_ReadModuloReg(FTM0_BASE_PTR)); + *TicksPtr = (TU1_TValueType)++tmp; + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : TU1_GetCounterValue (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the content of counter register. This method can be +** used both if counter is enabled and if counter is disabled. +** The method is not available if HW doesn't allow reading of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Counter value (number of counted ticks). +*/ +/* ===================================================================*/ +TU1_TValueType TU1_GetCounterValue(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + return (TU1_TValueType)FTM_PDD_ReadCounterReg(FTM0_BASE_PTR); +} + +/* +** =================================================================== +** Method : TU1_SetOffsetTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Sets the new offset value to channel specified by the +** parameter ChannelIdx. It is user responsibility to use value +** below selected period. This method is available when at +** least one channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** Ticks - Number of counter ticks to compare +** match. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range. +** ERR_NOTAVAIL - The compare mode is not +** selected for selected channel +** ERR_PARAM_TICKS - Ticks parameter is out of +** possible range. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_SetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, TU1_TValueType Ticks) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + /* Parameter test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (ChannelIdx > LAST_CHANNEL) { /* Is the channel index out of range? */ + return ERR_PARAM_INDEX; /* If yes then error */ + } + if ((ChannelMode[ChannelIdx]) != 0U) { /* Is the channel in compare mode? */ + return ERR_NOTAVAIL; /* If not then error */ + } + FTM_PDD_WriteChannelValueReg(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], (uint16_t)Ticks); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : TU1_GetOffsetTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the number of counter ticks to compare match channel +** specified by the parameter ChannelIdx. See also method +** [SetOffsetTicks]. This method is available when at least one +** channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** TicksPtr - Pointer to return value of the +** number of counter ticks to compare match. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range. +** ERR_NOTAVAIL - The compare mode is not +** selected for selected channel. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_GetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, TU1_TValueType *TicksPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + /* Parameter test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (ChannelIdx > LAST_CHANNEL) { /* Is the channel index out of range? */ + return ERR_PARAM_INDEX; /* If yes then error */ + } + if ((ChannelMode[ChannelIdx]) != 0U) { /* Is the channel in compare mode? */ + return ERR_NOTAVAIL; /* If not then error */ + } + *TicksPtr = (TU1_TValueType)(FTM_PDD_ReadChannelValueReg(FTM0_BASE_PTR, ChannelDevice[ChannelIdx])); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : TU1_SelectOutputAction (component TimerUnit_LDD) +*/ +/*! +** @brief +** Sets the type of compare match and counter overflow action +** on channel output. This method is available when at least +** one channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** CompareAction - Select output action +** on compare match +** @param +** CounterAction - Select output action +** on counter overflow +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range +** ERR_NOTAVAIL - Action is not possible on +** selected channel or counter. Supported +** combinations are HW specific. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_SelectOutputAction(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, LDD_TimerUnit_TOutAction CompareAction, LDD_TimerUnit_TOutAction CounterAction) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + /* Parameter test - this test can be disabled by setting the "Ignore range checking" + property to the "yes" value in the "Configuration inspector" */ + if (ChannelIdx > LAST_CHANNEL) { /* Is the channel index out of range? */ + return ERR_PARAM_INDEX; /* If yes then error */ + } + if ((ChannelMode[ChannelIdx]) != 0U) { /* Is the channel in compare mode? */ + return ERR_NOTAVAIL; /* If not then error */ + } + switch (CounterAction) { + case OUTPUT_NONE: + FTM_PDD_SelectChannelMode(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_OUTPUT_TOGGLE); + switch (CompareAction) { + case OUTPUT_NONE: + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_NONE); + break; + case OUTPUT_TOGGLE: + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_RISING); + break; + case OUTPUT_CLEAR: + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_FALLING); + break; + case OUTPUT_SET: + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_BOTH); + break; + default: + return ERR_NOTAVAIL; + } + break; + case OUTPUT_CLEAR: + if (CompareAction != OUTPUT_SET) { + return ERR_NOTAVAIL; + } + FTM_PDD_SelectChannelMode(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_OUTPUT_CLEAR); + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_BOTH); + break; + case OUTPUT_SET: + if (CompareAction != OUTPUT_CLEAR) { + return ERR_NOTAVAIL; + } + FTM_PDD_SelectChannelMode(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_OUTPUT_SET); + FTM_PDD_SelectChannelEdgeLevel(FTM0_BASE_PTR, ChannelDevice[ChannelIdx], FTM_PDD_EDGE_FALLING); + break; + default: + return ERR_NOTAVAIL; + } + return ERR_OK; /* OK */ +} + +/* END TU1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.h new file mode 100644 index 0000000..81f4f14 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU1.h @@ -0,0 +1,359 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 10:09, # CodeGen: 9 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU1 +** Module name : FTM0 +** Counter : FTM0_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : uint16_t +** Input clock source : Internal +** Counter frequency : Auto select +** Counter restart : On-match +** Period device : FTM0_MOD +** Period : 1 kHz +** Interrupt : Disabled +** Channel list : 2 +** Channel 0 : +** Mode : Compare +** Compare : FTM0_C0V +** Offset : 0 ms +** Output on compare : Clear +** Output on overrun : Set +** Initial state : High +** Output pin : ADC0_SE15/TSI0_CH14/PTC1/LLWU_P6/SPI0_PCS3/UART1_RTS_b/FTM0_CH0/I2S0_TXD0 +** Output pin signal : +** Interrupt : Disabled +** Channel 1 : +** Mode : Compare +** Compare : FTM0_C2V +** Offset : 0 ms +** Output on compare : Clear +** Output on overrun : Set +** Initial state : High +** Output pin : CMP1_IN1/PTC3/LLWU_P7/SPI0_PCS1/UART1_RX/FTM0_CH2/CLKOUTa/I2S0_TX_BCLK +** Output pin signal : +** Interrupt : Disabled +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Disabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); +** GetPeriodTicks - LDD_TError TU1_GetPeriodTicks(LDD_TDeviceData *DeviceDataPtr, TU1_TValueType... +** GetCounterValue - TU1_TValueType TU1_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); +** SetOffsetTicks - LDD_TError TU1_SetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** GetOffsetTicks - LDD_TError TU1_GetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** SelectOutputAction - LDD_TError TU1_SelectOutputAction(LDD_TDeviceData *DeviceDataPtr, uint8_t... +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU1.h +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU1_module TU1 module documentation +** @{ +*/ + +#ifndef __TU1_H +#define __TU1_H + +/* MODULE TU1. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ + +#include "FTM_PDD.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __BWUserType_TU1_TValueType +#define __BWUserType_TU1_TValueType + typedef uint16_t TU1_TValueType ; /* Type for data parameters of methods */ +#endif +#define TU1_CNT_INP_FREQ_U_0 0x017D7840UL /* Counter input frequency in Hz */ +#define TU1_CNT_INP_FREQ_R_0 25000000.0F /* Counter input frequency in Hz */ +#define TU1_CNT_INP_FREQ_COUNT 0U /* Count of predefined counter input frequencies */ +#define TU1_PERIOD_TICKS 0x61A8UL /* Initialization value of period in 'counter ticks' */ +#define TU1_NUMBER_OF_CHANNELS 0x02U /* Count of predefined channels */ +#define TU1_COUNTER_WIDTH 0x10U /* Counter width in bits */ +#define TU1_COUNTER_DIR DIR_UP /* Direction of counting */ +#define TU1_OFFSET_0_TICKS 0x00ul /* Initialization value of offset as 'counter ticks' for channel 0 */ +#define TU1_OFFSET_1_TICKS 0x00ul /* Initialization value of offset as 'counter ticks' for channel 1 */ +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define TU1_PRPH_BASE_ADDRESS 0x40038000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define TU1_Init_METHOD_ENABLED /*!< Init method of the component TU1 is enabled (generated) */ +#define TU1_GetPeriodTicks_METHOD_ENABLED /*!< GetPeriodTicks method of the component TU1 is enabled (generated) */ +#define TU1_GetCounterValue_METHOD_ENABLED /*!< GetCounterValue method of the component TU1 is enabled (generated) */ +#define TU1_SetOffsetTicks_METHOD_ENABLED /*!< SetOffsetTicks method of the component TU1 is enabled (generated) */ +#define TU1_GetOffsetTicks_METHOD_ENABLED /*!< GetOffsetTicks method of the component TU1 is enabled (generated) */ +#define TU1_SelectOutputAction_METHOD_ENABLED /*!< SelectOutputAction method of the component TU1 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ + + + +/* +** =================================================================== +** Method : TU1_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : TU1_GetPeriodTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the number of counter ticks before re-initialization. +** See also method [SetPeriodTicks]. This method is available +** only if the property ["Counter restart"] is switched to +** 'on-match' value. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** TicksPtr - Pointer to return value of the +** number of counter ticks before +** re-initialization +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_GetPeriodTicks(LDD_TDeviceData *DeviceDataPtr, TU1_TValueType *TicksPtr); + +/* +** =================================================================== +** Method : TU1_GetCounterValue (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the content of counter register. This method can be +** used both if counter is enabled and if counter is disabled. +** The method is not available if HW doesn't allow reading of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Counter value (number of counted ticks). +*/ +/* ===================================================================*/ +TU1_TValueType TU1_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : TU1_SetOffsetTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Sets the new offset value to channel specified by the +** parameter ChannelIdx. It is user responsibility to use value +** below selected period. This method is available when at +** least one channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** Ticks - Number of counter ticks to compare +** match. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range. +** ERR_NOTAVAIL - The compare mode is not +** selected for selected channel +** ERR_PARAM_TICKS - Ticks parameter is out of +** possible range. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_SetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, TU1_TValueType Ticks); + +/* +** =================================================================== +** Method : TU1_GetOffsetTicks (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the number of counter ticks to compare match channel +** specified by the parameter ChannelIdx. See also method +** [SetOffsetTicks]. This method is available when at least one +** channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** TicksPtr - Pointer to return value of the +** number of counter ticks to compare match. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range. +** ERR_NOTAVAIL - The compare mode is not +** selected for selected channel. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_GetOffsetTicks(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, TU1_TValueType *TicksPtr); + +/* +** =================================================================== +** Method : TU1_SelectOutputAction (component TimerUnit_LDD) +*/ +/*! +** @brief +** Sets the type of compare match and counter overflow action +** on channel output. This method is available when at least +** one channel is configured. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @param +** ChannelIdx - Index of the component +** channel. +** @param +** CompareAction - Select output action +** on compare match +** @param +** CounterAction - Select output action +** on counter overflow +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_PARAM_INDEX - ChannelIdx parameter is +** out of possible range +** ERR_NOTAVAIL - Action is not possible on +** selected channel or counter. Supported +** combinations are HW specific. +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU1_SelectOutputAction(LDD_TDeviceData *DeviceDataPtr, uint8_t ChannelIdx, LDD_TimerUnit_TOutAction CompareAction, LDD_TimerUnit_TOutAction CounterAction); + +/* END TU1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __TU1_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.c new file mode 100644 index 0000000..0e9a7ee --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.c @@ -0,0 +1,240 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU2.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU2 +** Module name : FTM1 +** Counter : FTM1_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 7.8125 kHz +** Counter restart : On-overrun +** Overrun period : Auto select +** Interrupt : Disabled +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Disabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr); +** ResetCounter - LDD_TError TU2_ResetCounter(LDD_TDeviceData *DeviceDataPtr); +** GetCounterValue - TU2_TValueType TU2_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU2.c +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU2_module TU2 module documentation +** @{ +*/ + +/* MODULE TU2. */ + +#include "TU2.h" +#include "FreeRTOS.h" /* FreeRTOS interface */ +#include "IO_Map.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct { + LDD_TUserData *UserDataPtr; /* RTOS device data structure */ +} TU2_TDeviceData; + +typedef TU2_TDeviceData *TU2_TDeviceDataPtr; /* Pointer to the device data structure. */ + +/* {FreeRTOS RTOS Adapter} Static object used for simulation of dynamic driver memory allocation */ +static TU2_TDeviceData DeviceDataPrv__DEFAULT_RTOS_ALLOC; + + +/* Internal method prototypes */ +/* +** =================================================================== +** Method : TU2_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr) +{ + /* Allocate device structure */ + TU2_TDeviceData *DeviceDataPrv; + /* {FreeRTOS RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ + DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; + DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ + /* SIM_SCGC6: FTM1=1 */ + SIM_SCGC6 |= SIM_SCGC6_FTM1_MASK; + /* FTM1_MODE: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,FAULTIE=0,FAULTM=0,CAPTEST=0,PWMSYNC=0,WPDIS=1,INIT=0,FTMEN=0 */ + FTM1_MODE = (FTM_MODE_FAULTM(0x00) | FTM_MODE_WPDIS_MASK); /* Set up mode register */ + /* FTM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=0,PS=0 */ + FTM1_SC = (FTM_SC_CLKS(0x00) | FTM_SC_PS(0x00)); /* Clear status and control register */ + /* FTM1_CNTIN: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,INIT=0 */ + FTM1_CNTIN = FTM_CNTIN_INIT(0x00); /* Clear counter initial register */ + /* FTM1_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ + FTM1_CNT = FTM_CNT_COUNT(0x00); /* Reset counter register */ + /* FTM1_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM1_C0SC = 0x00U; /* Clear channel status and control register */ + /* FTM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ + FTM1_C1SC = 0x00U; /* Clear channel status and control register */ + /* FTM1_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0xFFFF */ + FTM1_MOD = FTM_MOD_MOD(0xFFFF); /* Set up modulo register */ + /* FTM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TOF=0,TOIE=0,CPWMS=0,CLKS=2,PS=2 */ + FTM1_SC = (FTM_SC_CLKS(0x02) | FTM_SC_PS(0x02)); /* Set up status and control register */ + /* Registration of the device structure */ + PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU2_ID,DeviceDataPrv); + return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ +} + +/* +** =================================================================== +** Method : TU2_ResetCounter (component TimerUnit_LDD) +*/ +/*! +** @brief +** Resets counter. If counter is counting up then it is set to +** zero. If counter is counting down then counter is updated to +** the reload value. +** The method is not available if HW doesn't allow resetting of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU2_ResetCounter(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + FTM_PDD_InitializeCounter(FTM1_BASE_PTR); + return ERR_OK; /* OK */ +} + +/* +** =================================================================== +** Method : TU2_GetCounterValue (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the content of counter register. This method can be +** used both if counter is enabled and if counter is disabled. +** The method is not available if HW doesn't allow reading of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Counter value (number of counted ticks). +*/ +/* ===================================================================*/ +TU2_TValueType TU2_GetCounterValue(LDD_TDeviceData *DeviceDataPtr) +{ + (void)DeviceDataPtr; /* Parameter is not used, suppress unused argument warning */ + return (TU2_TValueType)FTM_PDD_ReadCounterReg(FTM1_BASE_PTR); +} + +/* END TU2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.h new file mode 100644 index 0000000..948fc5d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/TU2.h @@ -0,0 +1,226 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : TU2.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : TimerUnit_LDD +** Version : Component 01.164, Driver 01.11, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-12, 19:30, # CodeGen: 1 +** Abstract : +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +** Settings : +** Component name : TU2 +** Module name : FTM1 +** Counter : FTM1_CNT +** Counter direction : Up +** Counter width : 16 bits +** Value type : Optimal +** Input clock source : Internal +** Counter frequency : 7.8125 kHz +** Counter restart : On-overrun +** Overrun period : Auto select +** Interrupt : Disabled +** Channel list : 0 +** Initialization : +** Enabled in init. code : yes +** Auto initialization : no +** Event mask : +** OnCounterRestart : Disabled +** OnChannel0 : Disabled +** OnChannel1 : Disabled +** OnChannel2 : Disabled +** OnChannel3 : Disabled +** OnChannel4 : Disabled +** OnChannel5 : Disabled +** OnChannel6 : Disabled +** OnChannel7 : Disabled +** CPU clock/configuration selection : +** Clock configuration 0 : This component enabled +** Clock configuration 1 : This component disabled +** Clock configuration 2 : This component disabled +** Clock configuration 3 : This component disabled +** Clock configuration 4 : This component disabled +** Clock configuration 5 : This component disabled +** Clock configuration 6 : This component disabled +** Clock configuration 7 : This component disabled +** Contents : +** Init - LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr); +** ResetCounter - LDD_TError TU2_ResetCounter(LDD_TDeviceData *DeviceDataPtr); +** GetCounterValue - TU2_TValueType TU2_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file TU2.h +** @version 01.11 +** @brief +** This TimerUnit component provides a low level API for unified hardware access across +** various timer devices using the Prescaler-Counter-Compare-Capture timer structure. +*/ +/*! +** @addtogroup TU2_module TU2 module documentation +** @{ +*/ + +#ifndef __TU2_H +#define __TU2_H + +/* MODULE TU2. */ + +/* Include shared modules, which are used for whole project */ +#include "PE_Types.h" +#include "PE_Error.h" +#include "PE_Const.h" +#include "IO_Map.h" +/* Include inherited beans */ + +#include "FTM_PDD.h" +#include "Cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifndef __BWUserType_TU2_TValueType +#define __BWUserType_TU2_TValueType + typedef uint32_t TU2_TValueType ; /* Type for data parameters of methods */ +#endif +#define TU2_CNT_INP_FREQ_U_0 0x1E84UL /* Counter input frequency in Hz */ +#define TU2_CNT_INP_FREQ_R_0 7812.5F /* Counter input frequency in Hz */ +#define TU2_CNT_INP_FREQ_COUNT 0U /* Count of predefined counter input frequencies */ +#define TU2_PERIOD_TICKS 0x00010000UL /* Initialization value of period in 'counter ticks' */ +#define TU2_NUMBER_OF_CHANNELS 0x00U /* Count of predefined channels */ +#define TU2_COUNTER_WIDTH 0x10U /* Counter width in bits */ +#define TU2_COUNTER_DIR DIR_UP /* Direction of counting */ +/*! Peripheral base address of a device allocated by the component. This constant can be used directly in PDD macros. */ +#define TU2_PRPH_BASE_ADDRESS 0x40039000U + +/* Methods configuration constants - generated for all enabled component's methods */ +#define TU2_Init_METHOD_ENABLED /*!< Init method of the component TU2 is enabled (generated) */ +#define TU2_ResetCounter_METHOD_ENABLED /*!< ResetCounter method of the component TU2 is enabled (generated) */ +#define TU2_GetCounterValue_METHOD_ENABLED /*!< GetCounterValue method of the component TU2 is enabled (generated) */ + +/* Events configuration constants - generated for all enabled component's events */ + + + +/* +** =================================================================== +** Method : TU2_Init (component TimerUnit_LDD) +*/ +/*! +** @brief +** Initializes the device. Allocates memory for the device data +** structure, allocates interrupt vectors and sets interrupt +** priority, sets pin routing, sets timing, etc. If the +** property ["Enable in init. code"] is set to "yes" value then +** the device is also enabled (see the description of the +** [Enable] method). In this case the [Enable] method is not +** necessary and needn't to be generated. This method can be +** called only once. Before the second call of Init the [Deinit] +** must be called first. +** @param +** UserDataPtr - Pointer to the user or +** RTOS specific data. This pointer will be +** passed as an event or callback parameter. +** @return +** - Pointer to the dynamically allocated private +** structure or NULL if there was an error. +*/ +/* ===================================================================*/ +LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr); + +/* +** =================================================================== +** Method : TU2_ResetCounter (component TimerUnit_LDD) +*/ +/*! +** @brief +** Resets counter. If counter is counting up then it is set to +** zero. If counter is counting down then counter is updated to +** the reload value. +** The method is not available if HW doesn't allow resetting of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Error code, possible codes: +** ERR_OK - OK +** ERR_SPEED - The component does not work in +** the active clock configuration +*/ +/* ===================================================================*/ +LDD_TError TU2_ResetCounter(LDD_TDeviceData *DeviceDataPtr); + +/* +** =================================================================== +** Method : TU2_GetCounterValue (component TimerUnit_LDD) +*/ +/*! +** @brief +** Returns the content of counter register. This method can be +** used both if counter is enabled and if counter is disabled. +** The method is not available if HW doesn't allow reading of +** the counter. +** @param +** DeviceDataPtr - Device data structure +** pointer returned by [Init] method. +** @return +** - Counter value (number of counted ticks). +*/ +/* ===================================================================*/ +TU2_TValueType TU2_GetCounterValue(LDD_TDeviceData *DeviceDataPtr); + +/* END TU2. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __TU2_H */ +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.c new file mode 100644 index 0000000..e625650 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.c @@ -0,0 +1,2758 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +/* MODULE UTIL1. */ + +#include "UTIL1.h" +#include /* for rand() */ + +/* Internal method prototypes */ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill); + +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief copy the string src into dst. It performs the same task as strncpy, except + - always terminates the result string. + - does not zero out the remaining part in dst. + Note: dstSize is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to copy +*/ +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + *dst = '\0'; +} + +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Concat the string src into dst. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] src The source string to add + */ +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the src in the destination */ + while (dstSize > 0 && *src != '\0') { + *dst++ = *src++; + dstSize--; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch) +{ + dstSize--; /* for zero byte */ + /* point to the end of the source */ + while (dstSize > 0 && *dst != '\0') { + dst++; + dstSize--; + } + /* copy the ch in the destination */ + if (dstSize > 0) { + *dst++ = ch; + } + /* terminate the string */ + *dst = '\0'; +} + +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit unsigned number to convert. + */ +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val) +{ + UTIL1_Num16uToStr(dst, dstSize, (uint16_t)val); +} + +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts an 8bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 8bit signed number to convert. + */ +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val) +{ + UTIL1_Num16sToStr(dst, dstSize, (int16_t)val); +} + +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit unsigned number to convert. + */ +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number into a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 16bit signed number to convert. + */ +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int16_t)(0x8000)) { /* special case 0x8000/-32768: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-32768"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = (int16_t)(-val); + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : ShiftRightAndFill (component Utility) +** +** Description : +** This method is internal. It is used by Processor Expert only. +** =================================================================== +*/ +static void ShiftRightAndFill(uint8_t *dst, uint8_t fill, uint8_t nofFill) +{ + signed char i, j; + + j = 0; + while(dst[j] != '\0') { + j++; + } + i = (signed char)nofFill; + if (i==j) { + /* nothing to do, we are done */ + } else if (i>j) { + while (j>=0) { + dst[i] = dst[j]; + i--; j--; + } + while(i>=0) { + dst[i] = fill; + i--; + } + } else { + /* hmmm, not enough space, return what we have, do nothing */ + } +} + +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 16bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num16uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit unsigned number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32uToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string, in a formatted way (like printf with "%0d"). + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize Size of the destination buffer, in uint8_ts. + \param[in] val The 32bit signed number to add + \param[in] fill Fill character, typically ' ' (like for "%2d" or '0' (for "%02d") + \param[in] nofFill Size for the format (right aligned) string, e.g. '2' for "%2d" +*/ +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + UTIL1_Num32sToStr(dst, dstSize, val); + ShiftRightAndFill(dst, fill, nofFill); +} + +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit unsigned number to add + */ +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val) +{ + unsigned char buf[sizeof("256")]; /* maximum buffer size we need */ + + UTIL1_Num8uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 8bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 8bit signed number to add + */ +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val) +{ + unsigned char buf[sizeof("-128")]; /* maximum buffer size we need */ + + UTIL1_Num8sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + */ +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + */ +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("32768")]; /* maximum buffer size we need */ + + UTIL1_Num16uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 16bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 16bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-32768")]; /* maximum buffer size we need */ + + UTIL1_Num16sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit unsigned number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit signed number to a string, in a formatted way (like printf with "%0d". + Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit signed number to add + \param[in] fill Fill character + \param[in] nofFill Number of fill characters + */ +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStrFormatted(buf, dstSize, val, fill, nofFill); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 8bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 8bit number to add + */ +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num) +{ + unsigned char buf[sizeof("FF")]; /* maximum buffer size we need */ + unsigned char hex; + + buf[2] = '\0'; + hex = (char)(num & 0x0F); + buf[1] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + hex = (char)((num>>4) & 0x0F); + buf[0] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 16bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 16bit number to add + */ +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num) +{ + unsigned char buf[sizeof("FFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[4] = '\0'; + i = 3; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 24bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 24bit number to add + */ +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[6] = '\0'; + i = 5; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Adds a 32bit number as hex value to a string. + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] num The 32bit number to add + */ +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num) +{ + unsigned char buf[sizeof("FFFFFFFF")]; /* maximum buffer size we need */ + unsigned char hex; + int8_t i; + + buf[8] = '\0'; + i = 7; + do { + hex = (char)(num & 0x0F); + buf[i] = (char)(hex + ((hex <= 9) ? '0' : ('A'-10))); + num >>= 4; /* next nibble */ + i--; + } while (i>=0); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit number to add + */ +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char buf[sizeof("-4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32sToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief appends a 32bit (unsigned long) number to a string. Always terminates the result string. + Note: count is the size of dst INCLUDING zero byte. + Precondition: src, dst != NULL + \param[in,out] dst Start of string buffer, where to append the number string + \param[in] dstSize The size of the buffer, including the zero byte + \param[in] val The 32bit unsigned number to add + */ +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char buf[sizeof("4294967295")]; /* maximum buffer size we need */ + + UTIL1_Num32uToStr(buf, sizeof(buf), val); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit signed number to convert. + */ +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + unsigned char sign = (unsigned char)(val < 0); + + if (val==(int32_t)(0x80000000)) { /* special case 0x80000000/-2147483648: prevent overflow below. */ + UTIL1_strcpy(dst, dstSize, (unsigned char*)"-2147483648"); + return; + } + dstSize--; /* for zero byte */ + if (sign) { + val = -val; + } + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + if (sign && dstSize > 0){ + ptr[i++] = '-'; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ +/*! + \brief Converts a 32bit signed number to a string. + \param[in,out] dst String buffer to store the number. + \param[in] dstSize Size of the destination buffer in uint8_ts. + \param[in] val 32bit unsigned number to convert. + */ +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val) +{ + unsigned char *ptr = ((unsigned char *)dst); + unsigned char i=0, j; + unsigned char tmp; + + dstSize--; /* for zero byte */ + if (val == 0 && dstSize > 0){ + ptr[i++] = '0'; + dstSize--; + } + while (val > 0 && dstSize > 0) { + ptr[i++] = (unsigned char)((val % 10) + '0'); + dstSize--; + val /= 10; + } + for(j=0; j<(i/2); j++) { /* swap buffer */ + tmp = ptr[j]; + ptr[j] = ptr[(i-j)-1]; + ptr[(i-j)-1] = tmp; + } + ptr[i] = '\0'; +} + +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ +bool UTIL1_IsLeapYear(uint16_t year) +{ + return ((((year%4)==0) && (year%100)!=0) || (year%400)==0); +} + +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day) +{ + /* see http://klausler.com/new-dayofweek.html */ + static const uint8_t skew[12] = {0,3,3,6,1,4,6,2,5,0,3,5}; + uint16_t sum; + + sum = (uint16_t)(year-1900); + sum += sum/4; + sum %= 7; + if (UTIL1_IsLeapYear(year) && (month==1 || month==2)) { + sum--; + } + sum += day; + sum %= 7; + sum += skew[month-1]; + sum %= 7; + return (uint8_t)sum; /* 0: Sunday, 1: Monday, 2: Tuesday, 3: Wednesday, ... */ +} + +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators) +{ + size_t lenCopied = 0, lenOverread = 0; + bool quoteMode = FALSE; /* quoteMode means the name is surrounded by ". In this mode, only a second single quote " + terminates the string. In !quoteMode a space or a '\0' may also terminate it correctly */ + bool res = ERR_OK; + #define IS_SPACE(ch) ((ch)==' '||(ch)=='\t'||(ch)=='\n'||(ch)=='\v'||(ch)=='\f'||(ch)=='\r') + + if (filename==NULL || (destname!=NULL && maxlen==0)) { + return ERR_FAILED; + } + if (filename[0] == '"') { /* translated mode */ + filename++; /* overread '"' */ + lenOverread++; + quoteMode=TRUE; + } + if (terminators == NULL) { + terminators = ""; + } + for (;;) { + if (quoteMode) { + if (filename[0] == '"') { + filename++; /* overread '"' */ + lenOverread++; + if (filename[0] != '"') { /* quoteMode is terminated by a single quote. A double quote is treated like a single quote and does not terminate it ! */ + break; /* successfully finished with this name */ + } /* else we copy the second quote " */ + } + if (filename[0] == '\0') { /* unexpected 0. stop */ + res = ERR_FAILED; + break; /* error case: no terminating double quote (") was found */ + } + } else { /* copy mode */ + if (IS_SPACE(filename[0]) || filename[0] == '\0' || strchr(terminators, filename[0]) != NULL) { /* !quoteMode is terminated by space, '\0' or by any char in terminators */ + break; + } + } + if (destname != NULL) { + if (lenCopied + 1 < maxlen) { + destname[0] = filename[0]; + destname++; + } else { + destname[0] = '\0'; /* terminate string */ + destname = NULL; /* avoid it to overwrite not allocated space */ + } + } + lenCopied++; + filename++; + } + if (destname != NULL) { + destname[0] = '\0'; + } + if (lenRead != NULL) { + *lenRead = lenCopied+lenOverread; + } + if (lenWritten != NULL) { + *lenWritten = lenCopied + 1; /* additionally a zero byte written */ + } + return res; +} + +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ +/*------------------------------------------------------------------------/ +/ Universal string handler for user console interface +/-------------------------------------------------------------------------/ +/ +/ Copyright (C) 2010, ChaN, all right reserved. +/ +/ * This software is a free software and there is NO WARRANTY. +/ * No restriction on use. You can use, modify and redistribute it for +/ personal, non-profit or commercial products UNDER YOUR RESPONSIBILITY. +/ * Redistributions of source code must retain the above copyright notice. +/ +/-------------------------------------------------------------------------*/ +#ifdef __HC12__ + #pragma MESSAGE DISABLE C12056 /* message about SP debug info */ +#endif +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res) +{ +/* 123 -5 0x3ff 0b1111 0377 3.25 w " + ^ 1st call returns 123 and next ptr + ^ 2nd call returns -5 and next ptr + ^ 3rd call returns 1023 and next ptr + ^ 4th call returns 15 and next ptr + ^ 5th call returns 255 and next ptr + ^ 6th call returns 3 and next ptr, caller needs to read '.' + ^ 7th call returns 25 and next ptr + ^ 8th call fails and returns ERR_FAILED +*/ + uint32_t val; + uint8_t c, r, s = 0; + + *res = 0; + while (**str==' ') { + (*str)++; /* Skip leading spaces */ + } + c = **str; + if (c == '-') { /* negative? */ + s = 1; + c = *(++(*str)); + } + if (c == '0') { + c = *(++(*str)); + switch (c) { + case 'x': /* hexadecimal */ + r = 16; c = *(++(*str)); + break; + case 'b': /* binary */ + r = 2; c = *(++(*str)); + break; + default: + if (c <= ' ' || c == '.') { + return ERR_OK; /* single zero */ + } + if (c < '0' || c > '9') { + return ERR_FAILED; /* invalid char */ + } + r = 8; /* octal */ + break; + } /* switch */ + } else { + if (c < '0' || c > '9') { + return ERR_FAILED; /* EOL or invalid char */ + } + r = 10; /* decimal */ + } + val = 0; + while (c > ' ' && c != '.') { + if (c >= 'a') c -= 0x20; + c -= '0'; + if (c >= 17) { + c -= 7; + if (c <= 9) return ERR_FAILED; /* invalid char */ + } + if (c >= r) return ERR_FAILED; /* invalid char for current radix */ + val = val * r + c; + c = *(++(*str)); + } /* while */ + if (s) val = 0 - val; /* apply sign if needed */ + *res = (long)val; + return ERR_OK; +} +#ifdef __HC12__ + #pragma MESSAGE DEFAULT C12056 /* message about SP debug info */ +#endif + +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year) +{ + /* precondition: string points to starting of date, e.g. "01.01.10" or "12.5.2010", and date is in format dd.mm.yy or dd.mm.yyyy */ + const unsigned char *p; + + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, day)==ERR_OK + && *day > 0 && *day <= 31 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal8uNumber(&p, month)==ERR_OK + && *month > 0 && *month <= 12 + && (*p=='.' || *p=='-') + ) + { + p++; + if ( UTIL1_ScanDecimal16uNumber(&p, year)==ERR_OK + && *year > 0 && *year <= 3000 /* hopefully this is enough :-) */ + ) + { + if (*year < 100) { + *year += 2000; /* transform '10' into '2010' */ + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + *day = 0; + *month = 0; + *year = 0; + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond) +{ + /* precondition: string points to starting of time string, e.g. "03:15:05" or "03:15:05,3" or "03:15:05,17", and time is in format hh:mm:ss[,hh] */ + const unsigned char *p; + #define SCAN_IS_DIGIT(ch) ((ch)>='0'&&(ch)<='9') + + *hour = 0; + *minute = 0; + *second = 0; + *hSecond = 0; + p = *str; + while(*p==' ') { + p++; /* skip leading spaces */ + } + if ( UTIL1_ScanDecimal8uNumber(&p, hour)==ERR_OK + && *hour <= 24 + && *p==':' + ) + { + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, minute)==ERR_OK + && *minute <= 60 + ) + { + if (*p==':') { /* there is more after the minute */ + p++; /* skip ':' */ + if ( UTIL1_ScanDecimal8uNumber(&p, second)==ERR_OK + && *second <= 60 + ) + { + if (*p==',') { /* we do have either ",z" or ",hh" */ + p++; /* skip ',' */ + if (SCAN_IS_DIGIT(*p)) { + if (SCAN_IS_DIGIT(*(p+1))) { /* ,hh format */ + *hSecond = (uint8_t)((*p-'0')*10 + *(p+1)-'0'); + return ERR_OK; + } else { /* ,z format */ + *hSecond = (uint8_t)((*p-'0')*10); + p++; + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else { + return ERR_FAILED; /* illegal format, not a number, e.g. ",x" */ + } + } + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } else if (*p==' ' || *p=='\0') { /* nothing more after the minute? Assume zero seconds */ + *str = p; /* advance pointer for caller */ + return ERR_OK; + } + } + } + return ERR_FAILED; /* wrong format */ +} + +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _8_NOF_DIGITS (3+1) + uint8_t nofDigits = _8_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint8_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_8_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint8_t val8u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal8uNumber(&p, &val8u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int8_t)(-(int8_t)val8u); + } else { + *val = (int8_t)val8u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _16_NOF_DIGITS (5+1) + uint8_t nofDigits = _16_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint16_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_16_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint16_t val16u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal16uNumber(&p, (uint16_t*)&val16u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int16_t)(-(int16_t)val16u); + } else { + *val = (int16_t)val16u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + #define _32_NOF_DIGITS (10+1) + uint8_t nofDigits = _32_NOF_DIGITS; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + while(*p>='0' && *p<='9' && nofDigits > 0) { + *val = (uint32_t)((*val)*10 + *p-'0'); + nofDigits--; + p++; + } /* while */ + if (nofDigits==0) { + return ERR_OVERFLOW; + } + if (nofDigits==_32_NOF_DIGITS) { /* no digits at all? */ + return ERR_FAILED; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val) +{ + /* Scans a decimal number, and stops at any non-number. Number can have any preceding spaces. */ + const unsigned char *p = *str; + bool isNeg; + uint32_t val32u; + uint8_t res; + + while(*p==' ') { /* skip leading spaces */ + p++; + } + *val = 0; + if (*p=='-') { + isNeg = TRUE; + p++; /* skip minus */ + } else { + isNeg = FALSE; + } + res = UTIL1_ScanDecimal32uNumber(&p, &val32u); + if (res != ERR_OK) { + return res; + } + if (isNeg) { + *val = (int32_t)(-(int32_t)val32u); + } else { + *val = (int32_t)val32u; + } + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros) +{ + /* scans e.g. "-3445.071" and returns -3445 in integral part, and 71 in fractional part */ + uint8_t res; + const unsigned char *p = *str; + + *integral = 0; + *fractional = 0; + *nofFractionalZeros = 0; + res = UTIL1_ScanDecimal32sNumber(&p, integral); + if (res != ERR_OK) { + return res; + } + if (*p=='.') { + p++; /* skip '.' */ + while (*p=='0') { /* count leading zeros */ + (*nofFractionalZeros)++; + p++; /* skip leading zero */ + } + if (*p>='0' && *p<='9') { /* number */ + res = UTIL1_ScanDecimal32uNumber(&p, fractional); + if (res != ERR_OK) { + return res; + } + } + } + *str = p; /* store parsing pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strcmp(const char *, const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strcmp() function +} +*/ + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ +/*** +int16_t UTIL1_strncmp(const char *, const char *, size_t size) +{ + /Method is implemented as macro in the header file as wrapper to the standard strncmp() function +} +*/ + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ +/*** +uint16_t UTIL1_strlen(const char *) +{ + Method is implemented as macro in the header file as wrapper to the standard strlen() function +} +*/ + +static bool isHexCharacter(unsigned char ch) { + /* returns TRUE if character is a hexadecimal character */ + return (ch>='0' && ch<='9') || (ch>='a' && ch<='f') || (ch>='A' && ch<='F'); +} + +static uint8_t PreScanHexNumber(const unsigned char **str) { + const unsigned char *p = *str; + + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (*p!='0') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip '0' */ + if (*p!='x') { /* must start with 0x */ + return ERR_FAILED; + } + p++; /* skip 'x' */ + *str = p; + return ERR_OK; +} + +static uint8_t HexToDec(const unsigned char **p, unsigned char *val) { + /* convert a hexadecimal character into a decimal value */ + unsigned char ch = **p; + + if (ch>='0' && ch<='9') { + *val = (unsigned char)(ch-'0'); + (*p)++; + return ERR_OK; + } else if (ch>='a' && ch<='f') { + *val = (unsigned char)(ch-'a'+10); + (*p)++; + return ERR_OK; + } else if (ch>='A' && ch<='F') { + *val = (unsigned char)(ch-'A'+10); + (*p)++; + return ERR_OK; + } + return ERR_FAILED; +} + +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 8; /* maximum number of digits to avoid overflow */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint32_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val) +{ + /* scans a decimal number, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 4; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint16_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number with 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + if (PreScanHexNumber(&p)!=ERR_OK) { /* skip leading spaces, and scan '0x' */ + return ERR_FAILED; + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val) +{ + /* scans a hex number without 0x, and stops at any non-number. Number can have any preceding zeros or spaces. */ + uint8_t nofDigits = 2; /* maximum number of digits to read */ + const unsigned char *p = *str; + uint8_t v; + + *val = 0; + while(*p==' ') { /* skip leading spaces */ + p++; /* skip space */ + } + if (!isHexCharacter(*p)) { /* not a valid hex number sequence */ + return ERR_FAILED; + } + while (nofDigits>0 && HexToDec(&p, &v)==ERR_OK) { + *val = (uint8_t)((*val)*16 + v); + nofDigits--; + } /* while */ + *str = p; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail) +{ + int i, j; + + i = (int)UTIL1_strlen((char*)str); + j = (int)UTIL1_strlen((char*)tail); + if (j>i) { /* str is smaller than tail */ + return 1; /* cannot match */ + } + /* compare strings */ + while(str[i]==tail[j]) { + i--; + j--; + if (j<0) { + return 0; /* match */ + } + } + return 1; /* !=0 means no match */ +} + +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail) +{ + /* cut the tail from the string */ + size_t strLen, tailLen; + + if (UTIL1_strtailcmp(str, tail)!=0) { /* check if tail is present */ + return ERR_FAILED; /* tail not found */ + } + tailLen = UTIL1_strlen((char*)tail); + strLen = UTIL1_strlen((char*)str); + /* write \0 to cut the tail */ + str[strLen-tailLen] = '\0'; + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num) +{ + if (num<0 && (num/100)==0) { /* e.g. -53 ==> write sign, as strcatNum32() below will not know that it is negative */ + UTIL1_chcat(dst, dstSize, '-'); + } + UTIL1_strcatNum32s(dst, dstSize, num/100); + UTIL1_chcat(dst, dstSize, '.'); + if (num<0) { + num = -num; + } + UTIL1_strcatNum16uFormatted(dst, dstSize, (uint16_t)((unsigned)num%100U), '0', 2); +} + +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr) +{ + int16_t i, len; + + len = (int16_t)UTIL1_strlen((char*)subStr); + for (i=0; *str!='\0'; i++, str++) { + if (UTIL1_strncmp((char*)str, (char*)subStr, len)==0) { + return i; /* found */ + } + } + return -1; /* not found */ +} + +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType) +{ + int i; + uint8_t res; + const unsigned char *p; + + if (nofValues<=1) { + return ERR_FAILED; /* need at least two values */ + } + p = *str; + for(i=0;i0) { + *buf++ = *p++; + bufSize--; + } + if (*p!='\"') { + return ERR_FAILED; /* no terminating double quote */ + } else { + p++; /* skip double quote */ + *buf = '\0'; /* terminate buffer */ + } + *cmd = p; /* advance pointer */ + return ERR_OK; +} + +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize) +{ + uint8_t *p; + size_t nof = 0; + + if (dstSize<2) { + return; /* hmm, really to small for anything than the zero byte? */ + } + p = dst; + while(*p != '\0') { /* find end of string */ + p++; + nof++; + } + UTIL1_strcat(dst+nof, dstSize-nof, src); /* add string */ + dstSize -= nof; + while(*p != '\0' && srcPadSize>0 && dstSize>1) { + p++; + srcPadSize--; + dstSize--; + } + while(srcPadSize>0 && dstSize>1) { + *p++ = padChar; /* add padding char */ + srcPadSize--; + dstSize--; + } + *p = '\0'; /* terminate string */ +} + +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint32_t integral; + uint32_t fractional, shift; + int i; + bool isNeg; + + isNeg = (bool)(val<0); + if (isNeg) { + val = -val; /* make it positive */ + } + integral = (uint32_t)(int32_t)val; + val = val-(float)integral; /* get rid of integral part */ + shift = 1; + for(i=0;i0) { + UTIL1_chcat(dst, dstSize, '.'); + UTIL1_strcatNum32uFormatted(dst, dstSize, fractional, '0', nofFracDigits); + } +} + +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits) +{ + uint8_t buf[32]; + + UTIL1_NumFloatToStr(buf, sizeof(buf), val, nofFracDigits); + UTIL1_strcat(dst, dstSize, buf); +} + +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint16_t UTIL1_GetValue16LE(uint8_t *dataP) +{ + return (uint16_t)((dataP[1]<<8)+(dataP[0])); +} + +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue24LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ +uint32_t UTIL1_GetValue32LE(uint8_t *dataP) +{ + return (uint32_t)(((uint32_t)dataP[3])<<24)+(((uint32_t)dataP[2])<<16)+(dataP[1]<<8)+(dataP[0]); +} + +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); /* MSB */ +} + +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); +} + +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP) +{ + dataP[0] = (uint8_t)(data&0xff); /* LSB */ + dataP[1] = (uint8_t)((data>>8)&0xff); + dataP[2] = (uint8_t)((data>>16)&0xff); + dataP[3] = (uint8_t)((data>>24)&0xff); +} + +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Deinit(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max) +{ +#if 0 /* original Arduino implementation */ + return (x-in_min)*(out_max-out_min)/(in_max-in_min)+out_min; +#else /* improved version, see https://github.com/arduino/Arduino/issues/2466 */ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +#endif +} + +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max) +{ + if (valmax) { + return max; + } + return val; +} + +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ +int32_t UTIL1_random(int32_t min, int32_t max) +{ + int32_t val; + + val = rand()%(max-min+1)+min; + return UTIL1_constrain(val, min, max); +} + +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_randomSetSeed(unsigned int seed) +{ + srand(seed); /* set random number generator seed */ +} + +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max) +{ + if ((in_max - in_min) > (out_max - out_min)) { + return (x - in_min) * (out_max - out_min+1) / (in_max - in_min+1) + out_min; + } else { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; + } +} +#endif + +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes) +{ + if (nofBytes==1) { + UTIL1_strcatNum8Hex(dst, dstSize, (uint8_t)num); + } else if (nofBytes==2) { + UTIL1_strcatNum16Hex(dst, dstSize, (uint16_t)num); + } else if (nofBytes==3) { + UTIL1_strcatNum24Hex(dst, dstSize, num); + } else { /* nofBytes==4 */ + UTIL1_strcatNum32Hex(dst, dstSize, num); + } +} + +/* END UTIL1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.h new file mode 100644 index 0000000..0993ab7 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1.h @@ -0,0 +1,1422 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : UTIL1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Utility +** Version : Component 01.160, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Contains various utility functions. +** Settings : +** Component name : UTIL1 +** Contents : +** strcpy - void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcat - void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +** strcatPad - void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src,... +** chcat - void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +** Num8sToStr - void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +** Num8uToStr - void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +** Num16sToStr - void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +** Num16uToStr - void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +** Num32uToStr - void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +** Num32sToStr - void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +** NumFloatToStr - void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t... +** Num16sToStrFormatted - void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** Num16uToStrFormatted - void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** Num32uToStrFormatted - void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** Num32sToStrFormatted - void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNum8u - void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +** strcatNum8s - void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +** strcatNum16u - void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +** strcatNum16s - void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +** strcatNum32u - void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +** strcatNum32s - void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +** strcatNum16uFormatted - void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val,... +** strcatNum16sFormatted - void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val,... +** strcatNum32uFormatted - void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val,... +** strcatNum32sFormatted - void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val,... +** strcatNumHex - void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t... +** strcatNum8Hex - void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +** strcatNum16Hex - void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +** strcatNum24Hex - void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32Hex - void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +** strcatNum32sDotValue100 - void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +** strcatNumFloat - void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t... +** IsLeapYear - bool UTIL1_IsLeapYear(uint16_t year); +** WeekDay - uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +** ReadEscapedName - uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t... +** xatoi - uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +** ScanDate - uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t... +** ScanTime - uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t... +** ScanDecimal8uNumber - uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +** ScanDecimal8sNumber - uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +** ScanDecimal16uNumber - uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +** ScanDecimal16sNumber - uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +** ScanDecimal32uNumber - uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +** ScanDecimal32sNumber - uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +** ScanDecimal32sDotNumber - uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t... +** ScanHex8uNumber - uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +** ScanHex8uNumberNoPrefix - uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +** ScanHex16uNumber - uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +** ScanHex32uNumber - uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +** ScanSeparatedNumbers - uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t... +** ScanDoubleQuotedString - uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf,... +** strcmp - int16_t UTIL1_strcmp(const char *, const char *); +** strncmp - int16_t UTIL1_strncmp(const char *, const char *, size_t size); +** strFind - int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +** strtailcmp - uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +** strlen - uint16_t UTIL1_strlen(const char *); +** strCutTail - uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +** GetValue16LE - uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +** GetValue24LE - uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +** GetValue32LE - uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +** SetValue16LE - void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +** SetValue24LE - void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +** SetValue32LE - void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +** map - int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min,... +** map64 - int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t... +** constrain - int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +** random - int32_t UTIL1_random(int32_t min, int32_t max); +** randomSetSeed - void UTIL1_randomSetSeed(unsigned int seed); +** Deinit - void UTIL1_Deinit(void); +** Init - void UTIL1_Init(void); +** +** * Copyright (c) 2014-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file UTIL1.h +** @version 01.00 +** @brief +** Contains various utility functions. +*/ +/*! +** @addtogroup UTIL1_module UTIL1 module documentation +** @{ +*/ + +#ifndef __UTIL1_H +#define __UTIL1_H + +/* MODULE UTIL1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "UTIL1config.h" /* configuration */ + +/* other includes needed */ +#include +#include /* for size_t */ +/* special version */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + UTIL1_SEP_NUM_TYPE_UINT8, /* uint8_t number type */ + UTIL1_SEP_NUM_TYPE_UINT8_HEX_NO_PREFIX /* uint8_t hex number type, no 0x prefix */ +} UTIL1_SeparatedNumberType; + +void UTIL1_strcpy(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcpy (component Utility) +** +** Description : +** Same as normal strcpy, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcat(uint8_t *dst, size_t dstSize, const unsigned char *src); +/* +** =================================================================== +** Method : strcat (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStr(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : Num16sToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16sToStrFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16sToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16s(uint8_t *dst, size_t dstSize, int16_t val); +/* +** =================================================================== +** Method : strcatNum16s (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16sFormatted(uint8_t *dst, size_t dstSize, int16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16sFormatted (component Utility) +** +** Description : +** Appends a 16bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8Hex(uint8_t *dst, size_t dstSize, uint8_t num); +/* +** =================================================================== +** Method : strcatNum8Hex (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16Hex(uint8_t *dst, size_t dstSize, uint16_t num); +/* +** =================================================================== +** Method : strcatNum16Hex (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32s(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : strcatNum32s (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStr(uint8_t *dst, size_t dstSize, int32_t val); +/* +** =================================================================== +** Method : Num32sToStr (component Utility) +** +** Description : +** Converts a signed 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum32Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +bool UTIL1_IsLeapYear(uint16_t year); +/* +** =================================================================== +** Method : IsLeapYear (component Utility) +** +** Description : +** Returns true if a given year is a leap year +** Parameters : +** NAME - DESCRIPTION +** year - Year, in the YYYY format. +** Returns : +** --- - If the year is a leap year or not. +** =================================================================== +*/ + +uint8_t UTIL1_WeekDay(uint16_t year, uint8_t month, uint8_t day); +/* +** =================================================================== +** Method : WeekDay (component Utility) +** +** Description : +** Returns the weekday for a given date >= 1.Jan.1900 +** Parameters : +** NAME - DESCRIPTION +** year - year in YYYY format +** month - month of the year (1: January, 2: +** February, etc) +** day - day of the moth (starting with 1) +** Returns : +** --- - Returns the weekday, 0 for Sunday, 1 for +** Monday, 2 for Tuesday, etc. +** =================================================================== +*/ + +void UTIL1_chcat(uint8_t *dst, size_t dstSize, uint8_t ch); +/* +** =================================================================== +** Method : chcat (component Utility) +** +** Description : +** Adds a single character to a zero byte terminated string +** buffer. It cares about buffer overflow. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** ch - character to append +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32u(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : strcatNum32u (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStr(uint8_t *dst, size_t dstSize, uint32_t val); +/* +** =================================================================== +** Method : Num32uToStr (component Utility) +** +** Description : +** Converts an unsigned 32bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32uFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32uFormatted (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32uToStrFormatted(uint8_t *dst, size_t dstSize, uint32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32uToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum24Hex(uint8_t *dst, size_t dstSize, uint32_t num); +/* +** =================================================================== +** Method : strcatNum24Hex (component Utility) +** +** Description : +** Appends a 32bit unsigned value to a string buffer as hex +** number (without a 0x prefix). Only 24bits are used. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ReadEscapedName(const unsigned char *filename, uint8_t *destname, size_t maxlen, size_t *lenRead, size_t *lenWritten, const char *terminators); +/* +** =================================================================== +** Method : ReadEscapedName (component Utility) +** +** Description : +** Scans an escaped name from a string. This is useful e.g. for +** double quoted file names. +** Parameters : +** NAME - DESCRIPTION +** * filename - the name to be copied. Names may +** be in quoted format +** * destname - the destination of the copy. +** Names are not in quoted format. destname +** may be NULL to get the other return values +** only +** maxlen - length allocated for destname +** * lenRead - length read in filename to copy +** the whole name. Note that filenames maybe +** space terminated, so *lenRead < +** strlen(filename) +** lenWritten - the size written in destname. +** In case of overflows in destname, +** lenWritten is still increased but destname +** no longer written. The have the string +** length in these cases use strlen(destname) +** terminators - additional characters +** where a name should terminate. May be NULL +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_xatoi(const unsigned char **str, int32_t *res); +/* +** =================================================================== +** Method : xatoi (component Utility) +** +** Description : +** Custom atoi() (ascii to int) implementation by Elm Chan +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string to scan. Returns until +** where it has scanned. +** * res - Pointer to where to store the result +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDate(const unsigned char **str, uint8_t *day, uint8_t *month, uint16_t *year); +/* +** =================================================================== +** Method : ScanDate (component Utility) +** +** Description : +** Scans a date in the format "dd.mm.yyyy" or "dd-mm-yyyy". For +** yy it will expand it to 20yy. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to the string to be scanned. The +** function advances the pointer. +** * day - Pointer to where to store the day value +** * month - Pointer to where to store the month +** value +** * year - Pointer to where to store the year value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanTime(const unsigned char **str, uint8_t *hour, uint8_t *minute, uint8_t *second, uint8_t *hSecond); +/* +** =================================================================== +** Method : ScanTime (component Utility) +** +** Description : +** Scans a time string in the format "hh:mm:ss,hh" with the +** part for the ",hh" is optional. +** Parameters : +** NAME - DESCRIPTION +** str - Pointer to the string to be scanned. The +** function advances the pointer. +** * hour - Pointer to where to store the hour value +** * minute - Pointer to where to store the minute +** value +** * second - Pointer to where to store the second +** value +** * hSecond - Pointer to scans the hundreds of +** second part. If not present in string, zero +** is stored +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16uNumber (component Utility) +** +** Description : +** Scans a decimal 16bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanDecimal8uNumber (component Utility) +** +** Description : +** Scans a decimal 8bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_Num16uToStr(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : Num16uToStr (component Utility) +** +** Description : +** Converts a signed 16bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8sToStr(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : Num8sToStr (component Utility) +** +** Description : +** Converts a signed 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num8uToStr(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : Num8uToStr (component Utility) +** +** Description : +** Converts an unsigned 8bit value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num16uToStrFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num16uToStrFormatted (component Utility) +** +** Description : +** Converts a 16bit unsigned value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Num32sToStrFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : Num32sToStrFormatted (component Utility) +** +** Description : +** Converts a 32bit signed value to string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16u(uint8_t *dst, size_t dstSize, uint16_t val); +/* +** =================================================================== +** Method : strcatNum16u (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum16uFormatted(uint8_t *dst, size_t dstSize, uint16_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum16uFormatted (component Utility) +** +** Description : +** Appends a 16bit unsigned value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum32sFormatted(uint8_t *dst, size_t dstSize, int32_t val, char fill, uint8_t nofFill); +/* +** =================================================================== +** Method : strcatNum32sFormatted (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer in a +** formatted way. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** fill - Fill character +** nofFill - Number of fill characters +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32uNumber (component Utility) +** +** Description : +** Scans a decimal 32bit unsigned number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum8u(uint8_t *dst, size_t dstSize, uint8_t val); +/* +** =================================================================== +** Method : strcatNum8u (component Utility) +** +** Description : +** Appends a 8bit unsigned value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNum8s(uint8_t *dst, size_t dstSize, signed char val); +/* +** =================================================================== +** Method : strcatNum8s (component Utility) +** +** Description : +** Appends a 8bit signed value to a string buffer. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +#define UTIL1_strcmp(str1, str2) \ + strcmp(str1, str2) + +/* +** =================================================================== +** Method : strcmp (component Utility) +** +** Description : +** Wrapper to the standard strcmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strncmp(str1, str2, size) \ + strncmp(str1, str2, size) + +/* +** =================================================================== +** Method : strncmp (component Utility) +** +** Description : +** Wrapper to the standard strncmp() routine +** Parameters : +** NAME - DESCRIPTION +** * str1 - Pointer to string +** * str2 - Pointer to string +** size - +** Returns : +** --- - Returns zero if the two strings are the +** same +** =================================================================== +*/ + +#define UTIL1_strlen(str) \ + strlen(str) + +/* +** =================================================================== +** Method : strlen (component Utility) +** +** Description : +** Wrapper to the standard strlen() function. +** Parameters : +** NAME - DESCRIPTION +** str - +** Returns : +** --- - size of strinig +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex32uNumber(const unsigned char **str, uint32_t *val); +/* +** =================================================================== +** Method : ScanHex32uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 32bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex16uNumber(const unsigned char **str, uint16_t *val); +/* +** =================================================================== +** Method : ScanHex16uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 16bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x.. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumber(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumber (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, starting with 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_strtailcmp(const uint8_t *str, const uint8_t *tail); +/* +** =================================================================== +** Method : strtailcmp (component Utility) +** +** Description : +** Compares the tail of a string and returns 0 if it matches, 1 +** otherwise +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string. This string is compared +** if it contains the tail. +** * tail - Pointer to tail string. +** Returns : +** --- - returns 0 if tail matches, -1 otherwise +** =================================================================== +*/ + +uint8_t UTIL1_strCutTail(uint8_t *str, uint8_t *tail); +/* +** =================================================================== +** Method : strCutTail (component Utility) +** +** Description : +** Removes a tailing substring from a string. The string passed +** will be modified (the tail is cut by writing a zero byte to +** the string!) +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string where to remove the tail +** * tail - Pointer to substring to remove +** Returns : +** --- - Error code, ERR_OK if no error, otherwise +** ERR_FAIL if tail is not found +** =================================================================== +*/ + +uint8_t UTIL1_ScanHex8uNumberNoPrefix(const unsigned char **str, uint8_t *val); +/* +** =================================================================== +** Method : ScanHex8uNumberNoPrefix (component Utility) +** +** Description : +** Scans a hexadecimal 8bit number, without 0x +** Parameters : +** NAME - DESCRIPTION +** str - String to scan, starting with 0x. It +** returns as well until where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatNum32sDotValue100(uint8_t *dst, size_t dstSize, int32_t num); +/* +** =================================================================== +** Method : strcatNum32sDotValue100 (component Utility) +** +** Description : +** Appends a 32bit signed value to a string buffer. The value +** is in 1/100 units. For example for the value -13456 it will +** append the string "-134.56" +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** Returns : Nothing +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal8sNumber(const unsigned char **str, signed char *val); +/* +** =================================================================== +** Method : ScanDecimal8sNumber (component Utility) +** +** Description : +** Scans a decimal 8bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal16sNumber(const unsigned char **str, int16_t *val); +/* +** =================================================================== +** Method : ScanDecimal16sNumber (component Utility) +** +** Description : +** Scans a decimal 16bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sNumber(const unsigned char **str, int32_t *val); +/* +** =================================================================== +** Method : ScanDecimal32sNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * val - Pointer to value +** Returns : +** --- - Error code +** =================================================================== +*/ + +int16_t UTIL1_strFind(uint8_t *str, uint8_t *subStr); +/* +** =================================================================== +** Method : strFind (component Utility) +** +** Description : +** Searches a substring inside a string and returns the +** position. +** Parameters : +** NAME - DESCRIPTION +** * str - Pointer to string which will be searched +** * subStr - Pointer to substring to search +** inside str +** Returns : +** --- - -1 if not found, otherwise the character +** index. +** =================================================================== +*/ + +uint8_t UTIL1_ScanSeparatedNumbers(const unsigned char **str, uint8_t *values, uint8_t nofValues, char separator, UTIL1_SeparatedNumberType numberType); +/* +** =================================================================== +** Method : ScanSeparatedNumbers (component Utility) +** +** Description : +** Scans multiple numbers separated by character, e.g. "123.68. +** 5.3" +** Parameters : +** NAME - DESCRIPTION +** str - String to scan. It returns as well until +** where it has scanned +** * values - Pointer to array where to store the +** values +** nofValues - Number of values in the array +** separator - Character separator, e.g. '.' +** numberType - type of number to scan +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDoubleQuotedString(const uint8_t **cmd, uint8_t *buf, size_t bufSize); +/* +** =================================================================== +** Method : ScanDoubleQuotedString (component Utility) +** +** Description : +** Scans a string inside double quotes and returns it without +** the double quotes. +** Parameters : +** NAME - DESCRIPTION +** cmd - Pointer to pointer to string to parse. +** This pointer will be advanced as much as +** parsing is done. +** * buf - Pointer to buffer where to store the string +** bufSize - Size of buffer in bytes +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint8_t UTIL1_ScanDecimal32sDotNumber(const unsigned char **str, int32_t *integral, uint32_t *fractional, uint8_t *nofFractionalZeros); +/* +** =================================================================== +** Method : ScanDecimal32sDotNumber (component Utility) +** +** Description : +** Scans a decimal 32bit signed number with a following dot +** (fractional part), e.g. "-34587.0248", it will return the +** (signed) integral and fractional part with number of +** fractional zeros. The function accepts as well numbers like +** "17" (no fractional part" or "17.0" +** Parameters : +** NAME - DESCRIPTION +** str - string to scan. It returns as well until +** where it has scanned +** * integral - Pointer to value before the dot +** * fractional - Pointer to value after the +** dot, e.g. 32 for "-134.0032" +** nofFractionalZeros - Number of +** fractional leading zeros, e.g. 2 for "-134. +** 0032" +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_strcatPad(uint8_t *dst, size_t dstSize, const unsigned char *src, char padChar, uint8_t srcPadSize); +/* +** =================================================================== +** Method : strcatPad (component Utility) +** +** Description : +** Same as normal strcat, but safe as it does not write beyond +** the buffer. The buffer will be filled with a pad character +** for a given length. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** * src - Pointer to source string. +** padChar - Character to be used for padding +** srcPadSize - To which size the src string +** has to be padded. +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_NumFloatToStr(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : NumFloatToStr (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of fractional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_strcatNumFloat(uint8_t *dst, size_t dstSize, float val, uint8_t nofFracDigits); +/* +** =================================================================== +** Method : strcatNumFloat (component Utility) +** +** Description : +** Converts a float value into a string. +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** val - Value to be converted. +** nofFracDigits - Number of factional +** digits to print +** Returns : Nothing +** =================================================================== +*/ + +uint16_t UTIL1_GetValue16LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue16LE (component Utility) +** +** Description : +** Returns a 16bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue24LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue24LE (component Utility) +** +** Description : +** Returns a 24bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +uint32_t UTIL1_GetValue32LE(uint8_t *dataP); +/* +** =================================================================== +** Method : GetValue32LE (component Utility) +** +** Description : +** Returns a 32bit Little Endian value from memory +** Parameters : +** NAME - DESCRIPTION +** * dataP - Pointer to memory +** Returns : +** --- - Error code +** =================================================================== +*/ + +void UTIL1_SetValue16LE(uint16_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue16LE (component Utility) +** +** Description : +** Stores a 16bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue24LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue24LE (component Utility) +** +** Description : +** Stores a 24bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_SetValue32LE(uint32_t data, uint8_t *dataP); +/* +** =================================================================== +** Method : SetValue32LE (component Utility) +** +** Description : +** Stores a 32bit value in memory as Little Endian +** Parameters : +** NAME - DESCRIPTION +** data - Value to store +** * dataP - Pointer to memory +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component Utility) +** +** Description : +** Driver De-Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void UTIL1_Init(void); +/* +** =================================================================== +** Method : Init (component Utility) +** +** Description : +** Driver Initialization +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +int32_t UTIL1_map(int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max); +/* +** =================================================================== +** Method : map (component Utility) +** +** Description : +** Maps a value from one range to another +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range minimum value +** out_max - output range maximum value +** Returns : +** --- - remapped value +** =================================================================== +*/ + +int32_t UTIL1_constrain(int32_t val, int32_t min, int32_t max); +/* +** =================================================================== +** Method : constrain (component Utility) +** +** Description : +** Makes sure that a given input value is inside a given range. +** Parameters : +** NAME - DESCRIPTION +** val - input value +** min - range minimum value +** max - range maximum value +** Returns : +** --- - the constrained value +** =================================================================== +*/ + +int32_t UTIL1_random(int32_t min, int32_t max); +/* +** =================================================================== +** Method : random (component Utility) +** +** Description : +** Provides a random value. You have to call intialize the +** random number generator with randomSetSeed() first! +** Parameters : +** NAME - DESCRIPTION +** min - range minimum value +** max - range maximum value +** Returns : +** --- - random value between min and max +** =================================================================== +*/ + +void UTIL1_randomSetSeed(unsigned int seed); +/* +** =================================================================== +** Method : randomSetSeed (component Utility) +** +** Description : +** Sets a seed for the random number generator +** Parameters : +** NAME - DESCRIPTION +** seed - seed to be used for random number +** generator +** Returns : Nothing +** =================================================================== +*/ + +#ifdef __GNUC__ /* HIWARE compiler does not support 64bit data types */ +int64_t UTIL1_map64(int64_t x, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max); +#endif +/* +** =================================================================== +** Method : map64 (component Utility) +** +** Description : +** Maps a value from one range to another, using 64bit math +** Parameters : +** NAME - DESCRIPTION +** x - value to be mapped +** in_min - input range minimum value +** in_max - input range maximum value +** out_min - output range maximum value +** out_max - +** Returns : +** --- - remapped value +** =================================================================== +*/ + +void UTIL1_strcatNumHex(uint8_t *dst, size_t dstSize, uint32_t num, uint8_t nofBytes); +/* +** =================================================================== +** Method : strcatNumHex (component Utility) +** +** Description : +** Appends a value as hex valalue to a string buffer as hex +** number (without a 0x prefix), with variable number of digits +** Parameters : +** NAME - DESCRIPTION +** * dst - Pointer to destination string +** dstSize - Size of the destination buffer (in +** bytes). +** num - Value to convert. +** nofBytes - Number of bytes to write +** Returns : Nothing +** =================================================================== +*/ + +/* END UTIL1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __UTIL1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1config.h new file mode 100644 index 0000000..10eda65 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/UTIL1config.h @@ -0,0 +1,13 @@ +/** + * \file + * \brief Configuration header file for Utility + * + * This header file is used to configure settings of the Utility module. + */ + +#ifndef __UTIL1_CONFIG_H +#define __UTIL1_CONFIG_H + +/* no configuration supported yet */ + +#endif /* __UTIL1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Vectors.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Vectors.c new file mode 100644 index 0000000..47f76ef --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/Vectors.c @@ -0,0 +1,195 @@ +/** ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : Vectors.c +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Version : Component 01.001, Driver 01.04, CPU db: 3.00.000 +** Repository : Kinetis +** Compiler : GNU C Compiler +** Date/Time : 2018-06-15, 12:37, # CodeGen: 10 +** Abstract : +** +** Settings : +** +** +** Copyright : 1997 - 2015 Freescale Semiconductor, Inc. +** All Rights Reserved. +** +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o Redistributions in binary form must reproduce the above copyright notice, this +** list of conditions and the following disclaimer in the documentation and/or +** other materials provided with the distribution. +** +** o Neither the name of Freescale Semiconductor, Inc. nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.freescale.com +** mail: support@freescale.com +** ###################################################################*/ +/*! +** @file Vectors.c +** @version 01.04 +** @brief +** +*/ +/*! +** @addtogroup Vectors_module Vectors module documentation +** @{ +*/ + + #include "Cpu.h" + #include "LED1.h" + #include "LEDpin1.h" + #include "BitIoLdd1.h" + #include "MCUC1.h" + #include "SW_FWD.h" + #include "BitIoLdd2.h" + #include "SW_REV.h" + #include "BitIoLdd3.h" + #include "SW_PEELER.h" + #include "BitIoLdd4.h" + #include "ENC1.h" + #include "BitIoLdd5.h" + #include "PWMA.h" + #include "PwmLdd1.h" + #include "TU1.h" + #include "DIRA.h" + #include "BitIoLdd6.h" + #include "DIRB.h" + #include "BitIoLdd7.h" + #include "PWMB.h" + #include "PwmLdd2.h" + #include "HMODE.h" + #include "BitIoLdd8.h" + #include "FRTOS1.h" + #include "RTOSCNTRLDD1.h" + #include "WAIT1.h" + #include "CLS1.h" + #include "XF1.h" + #include "CS1.h" + #include "LED2.h" + #include "LEDpin2.h" + #include "BitIoLdd9.h" + #include "AS1.h" + #include "ASerialLdd1.h" + #include "HF1.h" + #include "TU2.h" + #include "KIN1.h" + #include "RTT1.h" + #include "AS2.h" + #include "ASerialLdd2.h" + #include "UTIL1.h" + #include "Events.h" + + + /* ISR prototype */ + extern uint32_t __SP_INIT; + extern + #ifdef __cplusplus + "C" + #endif + void __thumb_startup( void ); + + + /*lint -esym(765,__vect_table) Disable MISRA rule (8.10) checking for symbols (__vect_table). Definition of the interrupt vector table placed by linker on a predefined location. */ + /*lint -save -e926 -e927 -e928 -e929 Disable MISRA rule (11.4) checking. Need to explicitly cast pointers to the general ISR for Interrupt vector table */ + + __attribute__ ((section (".vectortable"))) const tVectorTable __vect_table = { /* Interrupt vector table */ + + /* ISR name No. Address Pri Name Description */ + &__SP_INIT, /* 0x00 0x00000000 - ivINT_Initial_Stack_Pointer used by PE */ + { + (tIsrFunc)&__thumb_startup, /* 0x01 0x00000004 - ivINT_Initial_Program_Counter used by PE */ + (tIsrFunc)&Cpu_INT_NMIInterrupt, /* 0x02 0x00000008 -2 ivINT_NMI used by PE */ + (tIsrFunc)&HF1_HardFaultHandler, /* 0x03 0x0000000C -1 ivINT_Hard_Fault used by PE */ + (tIsrFunc)&Cpu_ivINT_Mem_Manage_Fault, /* 0x04 0x00000010 - ivINT_Mem_Manage_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Bus_Fault, /* 0x05 0x00000014 - ivINT_Bus_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Usage_Fault, /* 0x06 0x00000018 - ivINT_Usage_Fault unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved7, /* 0x07 0x0000001C - ivINT_Reserved7 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved8, /* 0x08 0x00000020 - ivINT_Reserved8 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved9, /* 0x09 0x00000024 - ivINT_Reserved9 unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved10, /* 0x0A 0x00000028 - ivINT_Reserved10 unused by PE */ + (tIsrFunc)&vPortSVCHandler, /* 0x0B 0x0000002C - ivINT_SVCall used by PE */ + (tIsrFunc)&Cpu_ivINT_DebugMonitor, /* 0x0C 0x00000030 - ivINT_DebugMonitor unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved13, /* 0x0D 0x00000034 - ivINT_Reserved13 unused by PE */ + (tIsrFunc)&vPortPendSVHandler, /* 0x0E 0x00000038 - ivINT_PendableSrvReq used by PE */ + (tIsrFunc)&vPortTickHandler, /* 0x0F 0x0000003C - ivINT_SysTick used by PE */ + (tIsrFunc)&Cpu_ivINT_DMA0, /* 0x10 0x00000040 - ivINT_DMA0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA1, /* 0x11 0x00000044 - ivINT_DMA1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA2, /* 0x12 0x00000048 - ivINT_DMA2 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA3, /* 0x13 0x0000004C - ivINT_DMA3 unused by PE */ + (tIsrFunc)&Cpu_ivINT_DMA_Error, /* 0x14 0x00000050 - ivINT_DMA_Error unused by PE */ + (tIsrFunc)&Cpu_ivINT_Reserved21, /* 0x15 0x00000054 - ivINT_Reserved21 unused by PE */ + (tIsrFunc)&Cpu_ivINT_FTFL, /* 0x16 0x00000058 - ivINT_FTFL unused by PE */ + (tIsrFunc)&Cpu_ivINT_Read_Collision, /* 0x17 0x0000005C - ivINT_Read_Collision unused by PE */ + (tIsrFunc)&Cpu_ivINT_LVD_LVW, /* 0x18 0x00000060 - ivINT_LVD_LVW unused by PE */ + (tIsrFunc)&Cpu_ivINT_LLW, /* 0x19 0x00000064 - ivINT_LLW unused by PE */ + (tIsrFunc)&Cpu_ivINT_Watchdog, /* 0x1A 0x00000068 - ivINT_Watchdog unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2C0, /* 0x1B 0x0000006C - ivINT_I2C0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_SPI0, /* 0x1C 0x00000070 - ivINT_SPI0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2S0_Tx, /* 0x1D 0x00000074 - ivINT_I2S0_Tx unused by PE */ + (tIsrFunc)&Cpu_ivINT_I2S0_Rx, /* 0x1E 0x00000078 - ivINT_I2S0_Rx unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART0_LON, /* 0x1F 0x0000007C - ivINT_UART0_LON unused by PE */ + (tIsrFunc)&ASerialLdd1_Interrupt, /* 0x20 0x00000080 1 ivINT_UART0_RX_TX used by PE */ + (tIsrFunc)&ASerialLdd1_Interrupt, /* 0x21 0x00000084 1 ivINT_UART0_ERR used by PE */ + (tIsrFunc)&Cpu_ivINT_UART1_RX_TX, /* 0x22 0x00000088 - ivINT_UART1_RX_TX unused by PE */ + (tIsrFunc)&Cpu_ivINT_UART1_ERR, /* 0x23 0x0000008C - ivINT_UART1_ERR unused by PE */ + (tIsrFunc)&ASerialLdd2_Interrupt, /* 0x24 0x00000090 2 ivINT_UART2_RX_TX used by PE */ + (tIsrFunc)&ASerialLdd2_Interrupt, /* 0x25 0x00000094 2 ivINT_UART2_ERR used by PE */ + (tIsrFunc)&Cpu_ivINT_ADC0, /* 0x26 0x00000098 - ivINT_ADC0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMP0, /* 0x27 0x0000009C - ivINT_CMP0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMP1, /* 0x28 0x000000A0 - ivINT_CMP1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_FTM0, /* 0x29 0x000000A4 - ivINT_FTM0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_FTM1, /* 0x2A 0x000000A8 - ivINT_FTM1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_CMT, /* 0x2B 0x000000AC - ivINT_CMT unused by PE */ + (tIsrFunc)&Cpu_ivINT_RTC, /* 0x2C 0x000000B0 - ivINT_RTC unused by PE */ + (tIsrFunc)&Cpu_ivINT_RTC_Seconds, /* 0x2D 0x000000B4 - ivINT_RTC_Seconds unused by PE */ + (tIsrFunc)&RTOSCNTRLDD1_Interrupt, /* 0x2E 0x000000B8 8 ivINT_PIT0 used by PE */ + (tIsrFunc)&Cpu_ivINT_PIT1, /* 0x2F 0x000000BC - ivINT_PIT1 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT2, /* 0x30 0x000000C0 - ivINT_PIT2 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PIT3, /* 0x31 0x000000C4 - ivINT_PIT3 unused by PE */ + (tIsrFunc)&Cpu_ivINT_PDB0, /* 0x32 0x000000C8 - ivINT_PDB0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_USB0, /* 0x33 0x000000CC - ivINT_USB0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_USBDCD, /* 0x34 0x000000D0 - ivINT_USBDCD unused by PE */ + (tIsrFunc)&Cpu_ivINT_TSI0, /* 0x35 0x000000D4 - ivINT_TSI0 unused by PE */ + (tIsrFunc)&Cpu_ivINT_MCG, /* 0x36 0x000000D8 - ivINT_MCG unused by PE */ + (tIsrFunc)&Cpu_ivINT_LPTimer, /* 0x37 0x000000DC - ivINT_LPTimer unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTA, /* 0x38 0x000000E0 - ivINT_PORTA unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTB, /* 0x39 0x000000E4 - ivINT_PORTB unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTC, /* 0x3A 0x000000E8 - ivINT_PORTC unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTD, /* 0x3B 0x000000EC - ivINT_PORTD unused by PE */ + (tIsrFunc)&Cpu_ivINT_PORTE, /* 0x3C 0x000000F0 - ivINT_PORTE unused by PE */ + (tIsrFunc)&Cpu_ivINT_SWI /* 0x3D 0x000000F4 - ivINT_SWI unused by PE */ + } + }; + /*lint -restore Enable MISRA rule (11.4) checking. */ + + +/*! +** @} +*/ +/* +** ################################################################### +** +** This file was created by Processor Expert 10.5 [05.21] +** for the Freescale Kinetis series of microcontrollers. +** +** ################################################################### +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.c new file mode 100644 index 0000000..c94f12d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.c @@ -0,0 +1,351 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Enabled +** RTOS : FRTOS1 +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +/* MODULE WAIT1. */ + +#include "WAIT1.h" + + +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ +#if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif +#else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif +#endif +#endif +void WAIT1_Wait10Cycles(void) +{ + /* This function will wait 10 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ + +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + /* NOTE: Cortex-M0 and M4 have 1 cycle for a NOP */ + /* Compiler is GNUC */ + __asm ( + /* bl Wait10Cycles() to here: [4] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [4] for overhead */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +#ifdef __GNUC__ + #if MCUC1_CONFIG_CPU_IS_RISC_V /* naked is ignored for RISC-V gcc */ + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + #else + __attribute__((no_instrument_function)) + #endif + #else + #ifdef __cplusplus /* gcc 4.7.3 in C++ mode does not like no_instrument_function: error: can't set 'no_instrument_function' attribute after definition */ + __attribute__((naked)) + #else + __attribute__((naked, no_instrument_function)) + #endif + #endif +#endif +void WAIT1_Wait100Cycles(void) +{ + /* This function will spend 100 CPU cycles (including call overhead). */ + /*lint -save -e522 function lacks side effect. */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + __asm ( + /* bl to here: [4] */ + "push {r0} \n\t" /* [2] */ + "movs r0, #0 \n\t" /* [1] */ + "loop: \n\t" + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "add r0,#1 \n\t" /* [1] */ + "cmp r0,#9 \n\t" /* [1] */ + "bls loop \n\t" /* [3] taken, [1] not taken */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "nop \n\t" /* [1] */ + "pop {r0} \n\t" /* [2] */ + "bx lr \n\t" /* [3] */ + ); +#elif MCUC1_CONFIG_CPU_IS_RISC_V + /* \todo */ + __asm ( /* assuming [10] for overhead */ + " li a5,20 \n\t" + "Loop: \n\t" + " addi a5,a5,-1 \n\t" + " bgtz a5, Loop \n\t" + ); +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitCycles(uint16_t cycles) +{ + /*lint -save -e522 function lacks side effect. */ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter() 100) { + WAIT1_Wait100Cycles(); + counter -= 100; + } + while(counter > 10) { + WAIT1_Wait10Cycles(); + counter -= 10; + } +#endif + /*lint -restore */ +} + +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_WaitLongCycles(uint32_t cycles) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + uint32_t counter = cycles; + + counter += KIN1_GetCycleCounter(); + while(KIN1_GetCycleCounter()60000) { + WAIT1_WaitCycles(60000); + cycles -= 60000; + } + WAIT1_WaitCycles((uint16_t)cycles); + /*lint -restore */ +#endif +} + +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Waitms(uint16_t ms) +{ + /*lint -save -e522 function lacks side effect. */ + uint32_t msCycles; /* cycles for 1 ms */ + + /* static clock/speed configuration */ + msCycles = WAIT1_NofCyclesMs(1, WAIT1_INSTR_CLOCK_HZ); + while(ms>0) { + WAIT1_WaitLongCycles(msCycles); + ms--; + } + /*lint -restore */ +} +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ +/* implemented as macro version. See header file. */ +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +/* +void WAIT1_WaitOSms(void) +{ + Method is implemented as macro in the header file +} +*/ + +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void WAIT1_Init(void) +{ +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + /* init cycle counter */ + KIN1_InitCycleCounter(); + KIN1_ResetCycleCounter(); + KIN1_EnableCycleCounter(); +#endif +} + +/* END WAIT1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.h new file mode 100644 index 0000000..50c9e57 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1.h @@ -0,0 +1,259 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : WAIT1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : Wait +** Version : Component 01.085, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** Implements busy waiting routines. +** Settings : +** Component name : WAIT1 +** Manual Clock Values : Disabled +** Delay100usFunction : Delay100US +** RTOS : Enabled +** RTOS : FRTOS1 +** Watchdog : Disabled +** Contents : +** Wait10Cycles - void WAIT1_Wait10Cycles(void); +** Wait100Cycles - void WAIT1_Wait100Cycles(void); +** WaitCycles - void WAIT1_WaitCycles(uint16_t cycles); +** WaitLongCycles - void WAIT1_WaitLongCycles(uint32_t cycles); +** Waitms - void WAIT1_Waitms(uint16_t ms); +** Waitus - void WAIT1_Waitus(uint16_t us); +** Waitns - void WAIT1_Waitns(uint16_t ns); +** WaitOSms - void WAIT1_WaitOSms(void); +** Init - void WAIT1_Init(void); +** +** * Copyright (c) 2013-2019, Erich Styger +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file WAIT1.h +** @version 01.00 +** @brief +** Implements busy waiting routines. +*/ +/*! +** @addtogroup WAIT1_module WAIT1 module documentation +** @{ +*/ + +#ifndef __WAIT1_H +#define __WAIT1_H + +/* MODULE WAIT1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "WAIT1config.h" /* configuration */ + +/* other includes needed */ +#if WAIT1_CONFIG_USE_RTOS_WAIT + /* include RTOS header files */ + #include "FRTOS1.h" + #include "FreeRTOS.h" /* for vTaskDelay() */ + #include "task.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define WAIT1_INSTR_CLOCK_HZ CPU_CORE_CLK_HZ /* for Kinetis, use core clock as base for instruction execution */ +#else + extern uint32_t SystemCoreClock; /* clock frequency variable defined system_.h of the SDK */ + #define WAIT1_INSTR_CLOCK_HZ SystemCoreClock /* core clock frequency in Hz */ +#endif +#define WAIT1_NofCyclesMs(ms, hz) ((ms)*((hz)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesUs(us, hz) ((us)*(((hz)/1000)/1000)) /* calculates the needed cycles based on bus clock frequency */ +#define WAIT1_NofCyclesNs(ns, hz) (((ns)*(((hz)/1000)/1000))/1000) /* calculates the needed cycles based on bus clock frequency */ + +#define WAIT1_WAIT_C(cycles) \ + ( (cycles)<=10 ? \ + WAIT1_Wait10Cycles() \ + : WAIT1_WaitCycles((uint16_t)cycles) \ + ) /*!< wait for some cycles */ + + +void WAIT1_Wait10Cycles(void); +/* +** =================================================================== +** Method : Wait10Cycles (component Wait) +** +** Description : +** Wait for 10 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Wait100Cycles(void); +/* +** =================================================================== +** Method : Wait100Cycles (component Wait) +** +** Description : +** Wait for 100 CPU cycles. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitCycles(uint16_t cycles); +/* +** =================================================================== +** Method : WaitCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (16bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Waitms(uint16_t ms); +/* +** =================================================================== +** Method : Waitms (component Wait) +** +** Description : +** Wait for a specified time in milliseconds. +** Parameters : +** NAME - DESCRIPTION +** ms - How many milliseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitus(us) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesUs((us),WAIT1_INSTR_CLOCK_HZ)==0)||(us)==0) ? \ + (void)0 : \ + ( ((us)/1000)==0 ? (void)0 : WAIT1_Waitms((uint16_t)((us)/1000))) \ + , (WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)==0) ? (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesUs(((us)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitus (component Wait) +** +** Description : +** Wait for a specified time in microseconds. +** Parameters : +** NAME - DESCRIPTION +** us - How many microseconds the function has to +** wait +** Returns : Nothing +** =================================================================== +*/ + +/* we are having a static clock configuration: implement as macro/inlined version */ +#define WAIT1_Waitns(ns) \ + /*lint -save -e(505,506,522) Constant value Boolean, Redundant left argument to comma. */\ + ( ((WAIT1_NofCyclesNs((ns), WAIT1_INSTR_CLOCK_HZ)==0)||(ns)==0) ? \ + (void)0 : \ + WAIT1_Waitus((ns)/1000) \ + , (WAIT1_NofCyclesNs((ns)%1000, WAIT1_INSTR_CLOCK_HZ)==0) ? \ + (void)0 : \ + WAIT1_WAIT_C(WAIT1_NofCyclesNs(((ns)%1000), WAIT1_INSTR_CLOCK_HZ)) \ + /*lint -restore */\ + ) +/* +** =================================================================== +** Method : Waitns (component Wait) +** +** Description : +** Wait for a specified time in nano seconds. +** Parameters : +** NAME - DESCRIPTION +** ns - How many ns the function has to wait +** Returns : Nothing +** =================================================================== +*/ + +#if WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_WaitOSms(ms) vTaskDelay(pdMS_TO_TICKS(ms)) /* use FreeRTOS API */ +#else + #define WAIT1_WaitOSms(ms) WAIT1_Waitms(ms) /* use normal wait */ +#endif +/* +** =================================================================== +** Method : WaitOSms (component Wait) +** +** Description : +** If an RTOS is enabled, this routine will use a non-blocking +** wait method. Otherwise it will do a busy/blocking wait. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_WaitLongCycles(uint32_t cycles); +/* +** =================================================================== +** Method : WaitLongCycles (component Wait) +** +** Description : +** Wait for a specified number of CPU cycles (32bit data type). +** Parameters : +** NAME - DESCRIPTION +** cycles - The number of cycles to wait. +** Returns : Nothing +** =================================================================== +*/ + +void WAIT1_Init(void); +/* +** =================================================================== +** Method : Init (component Wait) +** +** Description : +** Driver initialization routine. +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END WAIT1. */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +/* ifndef __WAIT1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1config.h new file mode 100644 index 0000000..94b3860 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/WAIT1config.h @@ -0,0 +1,27 @@ +/** + * \file + * \brief Configuration header file for Wait + * + * This header file is used to configure settings of the busy waiting module. + */ + +#ifndef __WAIT1_CONFIG_H +#define __WAIT1_CONFIG_H + +#include "MCUC1.h" /* include library configuration */ + +#ifndef WAIT1_CONFIG_USE_CYCLE_COUNTER + #define WAIT1_CONFIG_USE_CYCLE_COUNTER (0 && (MCUC1_CONFIG_CONFIG_CPU_IS_ARM_CORTEX_M && MCUC1_CONFIG_CORTEX_M>=3)) + /*!< 1: Use hardware cycle counter (if present, only on Cortex-M3 or higher), 0: not using hardware cycle counter */ +#endif + +#ifndef WAIT1_CONFIG_USE_RTOS_WAIT + #define WAIT1_CONFIG_USE_RTOS_WAIT (1 && MCUC1_CONFIG_SDK_USE_FREERTOS) + /*!< 1: Use RTOS wait if RTOS is present; 0: use normal busy waiting */ +#endif + +#if WAIT1_CONFIG_USE_CYCLE_COUNTER + #include "KIN1.h" /* include Cortex utility functions */ +#endif + +#endif /* __WAIT1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.c new file mode 100644 index 0000000..8d2a857 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.c @@ -0,0 +1,1213 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2020-03-09, 06:38, # CodeGen: 15 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +/* MODULE XF1. */ +/** + * @file xformatc.c + * + * @brief Printf C implementation. + * + * Tested wuth the following operating systems / compilers : + * + * - Visual studio 6 + * - Visual studio 2008 / Windows CE + * - MinGw 32 + * - Linux i686 + * - Linux x86_64 + * - GCC wiith embedded ARM. + * - Linux armel + * - HCS08 with Freescale compiler. + * - SDCC (Z80 and 8051) + * + * @author Mario Viara + * + * + * @copyright Copyright Mario Viara 2014 - License Open Source (LGPL) + * This is a free software and is opened for education, research and commercial + * developments under license policy of following terms: + * + * - This is a free software and there is NO WARRANTY. + * - No restriction on use. You can use, modify and redistribute it for personal, + * non-profit or commercial product UNDER YOUR RESPONSIBILITY. + * - Redistributions of source code must retain the above copyright notice. + * + * To contact the author send an email to mario_at_viara.eu + * + */ +#include "XF1.h" + +/** + * Default largest int is long + */ +#ifndef LONG +#define LONG long +#endif + +/** + * Define the double type if not defined + */ +#ifndef DOUBLE +#define DOUBLE double +#endif + + +/** + * Default long long type + */ +#ifndef LONGLONG +#define LONGLONG long long +#endif + + +/** + * Definition to convert integer part of floating point + * number if supported we use the long long type + */ +#if XCFG_FORMAT_LONGLONG +#define FLOAT_LONG LONGLONG +#define FLOAT_VALUE llvalue +#define FLOAT_TYPE FLAG_TYPE_LONGLONG +#else +#define FLOAT_LONG LONG +#define FLOAT_VALUE lvalue +#define FLOAT_TYPE FLAG_TYPE_LONG +#endif + +/** + * Structure with all parameter used + */ +struct param_s +{ + /** + * Buffer for current integer value and for temporary + * double value defined as union to save stack. + */ + union + { + unsigned LONG lvalue; +#if XCFG_FORMAT_LONGLONG + unsigned LONGLONG llvalue; +#endif +#if XCFG_FORMAT_FLOAT + DOUBLE dvalue; +#endif + } values; + + /** + * Pointer to the output buffer + */ + char* out; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point argument + */ + DOUBLE dbl; + + /** + * Integer part of floating point + */ + unsigned FLOAT_LONG iPart; + +#endif + + + /** + * Current length of the output buffer + */ + int length; + + /** + * Field precision + */ + int prec; + + /** + * Field width + */ + int width; + + + /** + * Count the number of char emitted + */ + unsigned count; + + + /** + * Parser flags + */ + unsigned flags; + +#define FLAG_TYPE_INT 0x0000 /* Argument is integer */ +#define FLAG_TYPE_LONG 0x0001 /* Argument is long */ +#define FLAG_TYPE_SIZEOF 0x0002 /* Argument is size_t */ +#define FLAG_TYPE_LONGLONG 0x0003 /* Argument is long long */ +#define FLAG_TYPE_MASK 0x0003 /* Mask for field type */ +#define FLAG_PREC 0x0004 /* Precision set */ +#define FLAG_LEFT 0x0008 /* Left alignment */ +#define FLAG_BLANK 0x0010 /* Blank before positive integer number */ +#define FLAG_PREFIX 0x0020 /* Prefix required */ +#define FLAG_PLUS 0x0040 /* Force a + before positive number */ +#define FLAG_UPPER 0x0080 /* Output in upper case letter */ +#define FLAG_DECIMAL 0x0100 /* Decimal field */ +#define FLAG_INTEGER 0x0200 /* Integer field */ +#define FLAG_MINUS 0x0400 /* Field is negative */ +#define FLAG_VALUE 0x0800 /* Value set */ +#define FLAG_BUFFER 0x1000 /* Buffer set */ + + /** + * Length of the prefix + */ + int prefixlen; + + /* Buffer to store the field prefix */ + char prefix[2]; + + + /** Buffer to store the biggest integer number in binary */ +#if XCFG_FORMAT_LONGLONG + char buffer[sizeof(LONGLONG)*8+1]; +#else + char buffer[sizeof(LONG)*8+1]; +#endif + + /* Radix for ASCII integer conversion */ + unsigned char radix; + + /* char used for padding */ + char pad; + + + /** + * Current state + */ + char state; + +}; + + +/** + * Enum for the internal state machine + */ +enum State +{ + /* Normal state outputting literal */ + ST_NORMAL = 0, + /* Just read % */ + ST_PERCENT = 1, + + /* Just read flag */ + ST_FLAG = 2, + + /* Just read the width */ + ST_WIDTH = 3, + + /* Just read '.' */ + ST_DOT= 4, + + /* Just read the precision */ + ST_PRECIS = 5, + + /* Just read the size */ + ST_SIZE = 6, + + /* Just read the type specifier */ + ST_TYPE = 7 +}; + +/** + * Enum for char class + */ +enum CharClass +{ + /* Other char */ + CH_OTHER = 0, + /* The % char */ + CH_PERCENT = 1, + /* The . char */ + CH_DOT = 2, + /* The * char */ + CH_STAR = 3, + /* The 0 char */ + CH_ZERO = 4, + /* Digit 0-9 */ + CH_DIGIT = 5, + /* Flag chars */ + CH_FLAG = 6, + /* Size chars */ + CH_SIZE = 7, + /* Type chars */ + CH_TYPE = 8 +}; + + + +/** + * String used when %s is a null parameter + */ +static const char ms_null[] = "(null)"; +/* + * String for true value + */ +static const char ms_true[] = "True"; + +/** + * String for false value + */ +static const char ms_false[]= "False"; + + +/* + * Digit values + */ +static const char ms_digits[] = "0123456789abcdef"; + + +/* + * This table contains the next state for all char and it will be + * generate using xformattable.c + */ + +static const unsigned char formatStates[] = +{ + 0x06,0x00,0x00,0x06,0x00,0x01,0x00,0x00, + 0x10,0x00,0x03,0x06,0x00,0x06,0x02,0x10, + 0x04,0x45,0x45,0x45,0x45,0x05,0x05,0x05, + 0x05,0x35,0x30,0x00,0x50,0x60,0x00,0x00, + 0x00,0x20,0x28,0x38,0x50,0x50,0x00,0x00, + 0x00,0x30,0x30,0x30,0x50,0x50,0x00,0x00, + 0x08,0x20,0x20,0x28,0x20,0x20,0x20,0x00, + 0x08,0x60,0x60,0x60,0x60,0x60,0x60,0x00, + 0x00,0x70,0x78,0x78,0x78,0x70,0x78,0x00, + 0x07,0x08,0x00,0x00,0x07,0x00,0x00,0x08, + 0x08,0x00,0x00,0x08,0x00,0x08,0x00,0x00, + 0x08,0x00,0x07 +}; + + + + +/** + * Convert an unsigned value in one string + * + * All parameter are in the passed structure + * + * @param prec - Minimum precision + * @param lvalue - Unsigned value + * @param radix - Radix (Supported values 2/8/10/16) + * + * @param out - Buffer with the converted value. + */ +static void ulong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.lvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.lvalue & 0x01; + param->values.lvalue >>= 1; + break; + + case 8: + digit = param->values.lvalue & 0x07; + param->values.lvalue >>= 3; + break; + + case 16: + digit = param->values.lvalue & 0x0F; + param->values.lvalue >>= 4; + break; + + default: + case 10: + digit = param->values.lvalue % 10; + param->values.lvalue /= 10; + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} + + +#if XCFG_FORMAT_LONGLONG +#ifdef XCFG_FORMAT_LONG_ARE_LONGLONG +#define ullong2a ulong2a +#else +static void ullong2a(struct param_s * param) +{ + unsigned char digit; + + while (param->prec -- > 0 || param->values.llvalue) + { + switch (param->radix) + { + case 2: + digit = param->values.llvalue & 0x01; + param->values.llvalue >>= 1; + break; + + case 8: + digit = param->values.llvalue & 0x07; + param->values.llvalue >>= 3; + break; + + case 16: + digit = param->values.llvalue & 0x0F; + param->values.llvalue >>= 4; + break; + + default: + case 10: + digit = param->values.llvalue % 10; + param->values.llvalue /= 10; + + break; + } + + + *param->out -- = ms_digits[digit]; + param->length ++; + + } + +} +#endif +#endif + +#if 1 /* << EST */ +typedef struct { + char *s; + size_t space; +} StrOutBuffer; + +static void putCharIntoBufMaxLen(void *arg, char c) { + StrOutBuffer *buff = (StrOutBuffer*)arg; + if (buff->space > 0) { + buff->space--; + *(buff->s)++ = c; + } +} + +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args) { + int res = -1; + StrOutBuffer out; + + out.space = max_len; + out.s = buf; + if (max_len <= 1) { + *buf = 0; + return 0; + } else { + out.space--; /* teminal zero*/ + } + res = (int)XF1_xvformat(putCharIntoBufMaxLen, (void *)&out, fmt, args); + *(out.s) = 0; + if (res > 0) { + res = out.s - buf; + } + return res; +} +#endif + +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ +/** + * Printf like using variable arguments. + * + * @param outchar - Pointer to the function to output one new char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param ... - Arguments + * + * @return The number of char emitted. + * + * @see xvformat + */ +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) +{ + va_list list; + unsigned count; + + va_start(list,fmt); + count = XF1_xvformat(outchar,arg,fmt,list); + + va_end(list); + + return count; +} + +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +/** + * We do not want use any library function. + * + * @param s - C string + * @return The length of the string + */ +static unsigned xstrlen(const char *s) +{ + const char *i; + + for (i = s ; *i ; i++) + { + } + + return (unsigned)(i - s); +} + +static unsigned outBuffer(void (*myoutchar)(void *arg,char),void *arg,const char *buffer,int len,unsigned toupper) +{ + unsigned count = 0; + int i; + char c; + + for (i = 0; i < len ; i++) + { + c = buffer[i]; + + if (toupper && (c >= 'a' && c <= 'z')) + { + c -= 'a' - 'A'; + } + + (*myoutchar)(arg,c); + count++; + } + + return count; +} + + +static unsigned outChars(void (*myoutchar)(void *arg,char),void *arg,char ch,int len) +{ + unsigned count= 0; + + while (len-- > 0) + { + (*myoutchar)(arg,ch); + count++; + } + + return count; +} + +#if 1 /* << EST added xsprintf() */ +static void putCharIntoBuf(void *arg, char c) { + char **s = (char **)arg; + *(*s)++ = c; +} + +int xsprintf(char *buf, const char *fmt, va_list args) { + int res; + + res = (int)XF1_xvformat(putCharIntoBuf, (void *)&buf, fmt, args); + *buf = 0; + return res; +} +#endif + +/* + * Lint want declare list as const but list is an obscured pointer so + * the warning is disabled. + */ +/*lint -save -e818 */ + + +/** + * Printf like format function. + * + * General format : + * + * %[width][.precision][flags]type + * + * - width Is the minimum size of the field. + * + * - precision Is the maximum size of the field. + * + * Supported flags : + * + * - l With integer number the argument will be of type long. + * - ll With integer number the argument will be of type long long. + * - Space for positive integer a space will be added before. + * - z Compatible with C99 the argument is size_t (aka sizeof(void *)) + * - + A + sign prefix positive number. + * - # A prefix will be printed (o for octal,0x for hex,0b for binary) + * - 0 Value will be padded with zero (default is spacwe) + * - - Left justify as default filed have rigth justification. + * + * Supported type : + * + * - s Null terminated string of char. + * - S Null terminated string of char in upper case. + * - i Integer number. + * - d Integer number. + * - u Unsigned number. + * - x Unsigned number in hex. + * - X Unsigned number in hex upper case. + * - b Binary number + * - o Octal number + * - p Pointer will be emitted with the prefix -> + * - P Pointer in upper case letter. + * - f Floating point number. + * - B Boolean value printed as True / False. + * + * @param outchar - Pointer to the function to output one char. + * @param arg - Argument for the output function. + * @param fmt - Format options for the list of parameters. + * @param args - List parameters. + * + * @return The number of char emitted. + */ +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list _args) +{ + XCFG_FORMAT_STATIC struct param_s param; + int i; + char c; + +#if XCFG_FORMAT_VA_COPY + va_list args; + + va_copy(args,_args); +#else +#define args _args +#endif + + param.count = 0; + param.state = ST_NORMAL; + + while (*fmt) + { + c = *fmt++; + + if (c < ' ' || c > 'z') + i = (int)CH_OTHER; + else + i = formatStates[c - ' '] & 0x0F; + + param.state = formatStates[(i << 3) + param.state] >> 4; + + + switch (param.state) + { + default: + case ST_NORMAL: + (*outchar)(arg,c); + param.count++; + break; + + case ST_PERCENT: + param.flags = param.length = param.prefixlen = param.width = param.prec = 0; + param.pad = ' '; + break; + + case ST_WIDTH: + if (c == '*') + param.width = (int)va_arg(args,int); + else + param.width = param.width * 10 + (c - '0'); + break; + + case ST_DOT: + break; + + case ST_PRECIS: + param.flags |= FLAG_PREC; + if (c == '*') + param.prec = (int)va_arg(args,int); + else + param.prec = param.prec * 10 + (c - '0'); + break; + + case ST_SIZE: + switch (c) + { + default: + break; + case 'z': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_SIZEOF; + break; + + case 'l': +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONG) + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONGLONG; + } + else + { + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; + + } +#else + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_TYPE_LONG; +#endif + break; + + + } + break; + + case ST_FLAG: + switch (c) + { + default: + break; + case '-': + param.flags |= FLAG_LEFT; + break; + case '0': + param.pad = '0'; + break; + case ' ': + param.flags |= FLAG_BLANK; + break; + case '#': + param.flags |= FLAG_PREFIX; + break; + case '+': + param.flags |= FLAG_PLUS; + break; + } + break; + + case ST_TYPE: + switch (c) + { + default: + param.length = 0; + break; + + /* + * Pointer upper case + */ + case 'P': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Pointer + */ + case 'p': + param.flags &= ~FLAG_TYPE_MASK; + param.flags |= FLAG_INTEGER | FLAG_TYPE_SIZEOF; + param.radix = 16; + param.prec = sizeof(void *) * 2; + param.prefix[0] = '-'; + param.prefix[1] = '>'; + param.prefixlen = 2; + break; + + /* + * Binary number + */ + case 'b': + param.flags |= FLAG_INTEGER; + param.radix = 2; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'b'; + param.prefixlen = 2; + } + break; + + /* + * Octal number + */ + case 'o': + param.flags |= FLAG_INTEGER; + param.radix = 8; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefixlen = 1; + } + break; + + /* + * Hex number upper case letter. + */ + case 'X': + /* no break */ + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Hex number lower case + */ + case 'x': + param.flags |= FLAG_INTEGER; + param.radix = 16; + if (param.flags & FLAG_PREFIX) + { + param.prefix[0] = '0'; + param.prefix[1] = 'x'; + param.prefixlen = 2; + } + break; + + /* + * Integer number radix 10 + */ + case 'd': + case 'i': + param.flags |= FLAG_DECIMAL|FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Unsigned number + */ + case 'u': + param.flags |= FLAG_INTEGER; + param.radix = 10; + break; + + /* + * Upper case string + */ + case 'S': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /*lint -fallthrough */ + + /* + * Normal string + */ + case 's': + param.out = va_arg(args,char *); + if (param.out == 0) + param.out = (char *)ms_null; + param.length = (int)xstrlen(param.out); + break; + + /* + * Upper case char + */ + case 'C': + param.flags |= FLAG_UPPER; + // fall through + /* no break */ + /* lint -fallthrough */ + + /* + * Char + */ + case 'c': + param.out = param.buffer; + param.buffer[0] = (char)va_arg(args,int); + param.length = 1; + break; + +#if XCFG_FORMAT_FLOAT + /** + * Floating point number + */ + case 'f': + if (!(param.flags & FLAG_PREC)) + { + param.prec = 6; + } + + param.dbl = va_arg(args,DOUBLE); + param.values.dvalue = 0.50; + for (i = 0 ; i < param.prec ; i++) + param.values.dvalue /= 10.0; + + if (param.dbl < 0) + { + param.flags |= FLAG_MINUS; + param.dbl -= param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= (FLOAT_LONG)param.iPart; + param.dbl = - param.dbl; + } + else + { + param.dbl += param.values.dvalue; + param.iPart = (FLOAT_LONG)param.dbl; + param.dbl -= param.iPart; + } + + + for (i = 0 ;i < param.prec ;i++) + param.dbl *= 10.0; + + param.values.lvalue = (unsigned LONG)param.dbl; + + param.out = param.buffer + sizeof(param.buffer) - 1; + param.radix = 10; + if (param.prec) + { + ulong2a(¶m); + *param.out -- = '.'; + param.length ++; + } + param.flags |= FLAG_INTEGER | FLAG_BUFFER | + FLAG_DECIMAL | FLAG_VALUE | FLOAT_TYPE; + + param.prec = 0; + param.values.FLOAT_VALUE = (unsigned FLOAT_LONG)param.iPart; + break; +#endif + + /** + * Boolean value + */ + case 'B': + if (va_arg(args,int) != 0) + param.out = (char*)ms_true; + else + param.out = (char*)ms_false; + + param.length = (int)xstrlen(param.out); + break; + + + } + + /* + * Process integer number + */ + if (param.flags & FLAG_INTEGER) + { + if (param.prec == 0) + param.prec = 1; + + if (!(param.flags & FLAG_VALUE)) + { + switch (param.flags & FLAG_TYPE_MASK) + { + case FLAG_TYPE_SIZEOF: + param.values.lvalue = (unsigned LONG)va_arg(args,void *); + break; + case FLAG_TYPE_LONG: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,long); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned long); + break; + + case FLAG_TYPE_INT: + if (param.flags & FLAG_DECIMAL) + param.values.lvalue = (LONG)va_arg(args,int); + else + param.values.lvalue = (unsigned LONG)va_arg(args,unsigned int); + break; +#if XCFG_FORMAT_LONGLONG + case FLAG_TYPE_LONGLONG: + param.values.llvalue = (LONGLONG)va_arg(args,long long); + break; +#endif + } + + } + + if ((param.flags & FLAG_PREFIX) && param.values.lvalue == 0) + { + param.prefixlen = 0; + } + + + /* + * Manage signed integer + */ + if (param.flags & FLAG_DECIMAL) + { +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + { + if ((LONGLONG)param.values.llvalue < 0) + { + param.values.llvalue = ~param.values.llvalue + 1; + param.flags |= FLAG_MINUS; + } + } + else + { +#endif + if ((LONG)param.values.lvalue < 0) + { + param.values.lvalue = ~param.values.lvalue + 1; + param.flags |= FLAG_MINUS; + + } +#if XCFG_FORMAT_LONGLONG + } +#endif + if (!(param.flags & FLAG_MINUS) && (param.flags & FLAG_BLANK)) + { + param.prefix[0] = ' '; + param.prefixlen = 1; + } + } + + if ((param.flags & FLAG_BUFFER) == 0) + { + param.out = param.buffer + sizeof(param.buffer) - 1; + } + + +#if XCFG_FORMAT_LONGLONG + if ((param.flags & FLAG_TYPE_MASK) == FLAG_TYPE_LONGLONG) + ullong2a(¶m); + else + ulong2a(¶m); +#else + + ulong2a(¶m); +#endif + param.out++; + + /* + * Check if a sign is required + */ + if (param.flags & (FLAG_MINUS|FLAG_PLUS)) + { + c = param.flags & FLAG_MINUS ? '-' : '+'; + + if (param.pad == '0') + { + param.prefixlen = 1; + param.prefix[0] = c; + } + else + { + *--param.out = c; + param.length++; + } + } + + + } + else + { + if (param.width && param.length > param.width) + { + param.length = param.width; + } + + } + + /* + * Now width contain the size of the pad + */ + param.width -= (param.length + param.prefixlen); + + param.count += outBuffer(outchar,arg,param.prefix,param.prefixlen,param.flags & FLAG_UPPER); + if (!(param.flags & FLAG_LEFT)) + param.count += outChars(outchar,arg,param.pad,param.width); + param.count += outBuffer(outchar,arg,param.out,param.length,param.flags & FLAG_UPPER); + if (param.flags & FLAG_LEFT) + param.count += outChars(outchar,arg,param.pad,param.width); + + } + } + +#if XCFG_FORMAT_VA_COPY + va_end(args); +#endif + + return param.count; +} +/*lint -restore */ + +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsprintf(char *buf, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsprintf(buf, fmt, args); + va_end(args); + return res; +} + + +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) +{ + va_list args; + int res; + + va_start(args,fmt); + res = xsnprintf(buf, max_len, fmt, args); + va_end(args); + return res; +} + +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Init(void) +{ + /* nothing needed */ +} + +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ +void XF1_Deinit(void) +{ + /* nothing needed */ +} + +/* END XF1. */ + +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.h new file mode 100644 index 0000000..39af653 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1.h @@ -0,0 +1,191 @@ +/* ################################################################### +** This component module is generated by Processor Expert. Do not modify it. +** Filename : XF1.h +** Project : tinyk20_OpenPnP_AutoFeeder +** Processor : MK20DN128VFT5 +** Component : XFormat +** Version : Component 01.025, Driver 01.00, CPU db: 3.00.000 +** Compiler : GNU C Compiler +** Date/Time : 2019-10-19, 06:26, # CodeGen: 12 +** Abstract : +** +** Settings : +** +** Contents : +** xvformat - unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char *... +** xformat - unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char *... +** xsprintf - int XF1_xsprintf(char *buf, const char *fmt, ...); +** xsnprintf - int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...); +** Deinit - void XF1_Deinit(void); +** Init - void XF1_Init(void); +** +** * Copyright : (c) Copyright Mario Viara, 2014-2018, https://github.com/MarioViara/xprintfc +** * Adopted for Processor Expert: Erich Styger +** * xsnprintf() contributed by Engin Lee +** * Web: https://mcuoneclipse.com +** * SourceForge: https://sourceforge.net/projects/mcuoneclipse +** * Git: https://github.com/ErichStyger/McuOnEclipse_PEx +** * All rights reserved. +** * +** * Redistribution and use in source and binary forms, with or without modification, +** * are permitted provided that the following conditions are met: +** * +** * - Redistributions of source code must retain the above copyright notice, this list +** * of conditions and the following disclaimer. +** * +** * - Redistributions in binary form must reproduce the above copyright notice, this +** * list of conditions and the following disclaimer in the documentation and/or +** * other materials provided with the distribution. +** * +** * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** ###################################################################*/ +/*! +** @file XF1.h +** @version 01.00 +** @brief +** +*/ +/*! +** @addtogroup XF1_module XF1 module documentation +** @{ +*/ + +#ifndef __XF1_H +#define __XF1_H + +/* MODULE XF1. */ +#include "MCUC1.h" /* SDK and API used */ +#include "XF1config.h" /* configuration */ + +/* other includes needed */ +#include /* open argument list support */ +#include /* for size_t */ + +/* GCC have printf type attribute check. */ +#ifdef __GNUC__ + /* inform the GNU compiler about printf() style functions, so the compiler can check the arguments */ + #define XF1_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#else + #define XF1_PRINTF_ATTRIBUTE(a,b) +#endif /* __GNUC__ */ + +/* low level functions */ +int xsnprintf(char *buf, size_t max_len, const char *fmt, va_list args); +int xsprintf(char *buf, const char *fmt, va_list args); + +unsigned XF1_xformat(void (*outchar)(void *,char), void *arg, const char * fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xformat (component XFormat) +** +** Description : +** Printf() like function using variable arguments +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to output one new +** character +** arg - Argument for the output function +** fmt - Format options for the list of parameters +** openArgList - Open argument list +** Returns : +** --- - Error code +** =================================================================== +*/ + +unsigned XF1_xvformat(void (*outchar)(void *,char), void *arg, const char * fmt, va_list args); +/* +** =================================================================== +** Method : xvformat (component XFormat) +** +** Description : +** Printf() like format function +** Parameters : +** NAME - DESCRIPTION +** outchar - Function pointer to the function +** to output one char. +** * arg - Argument for the output function. +** fmt - Format options for the list of parameters. +** args - List of parameters +** Returns : +** --- - Error code +** =================================================================== +*/ + +int XF1_xsprintf(char *buf, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(2,3); +/* +** =================================================================== +** Method : xsprintf (component XFormat) +** +** Description : +** sprintf() like function +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +int XF1_xsnprintf(char *buf, size_t max_len, const char *fmt, ...) XF1_PRINTF_ATTRIBUTE(3,4); +/* +** =================================================================== +** Method : xsnprintf (component XFormat) +** +** Description : +** snprintf() like function, returns the number of characters +** written, negative in case of error. +** Parameters : +** NAME - DESCRIPTION +** * buf - Pointer to buffer to be written +** max_len - size of output buffer (in size) +** * fmt - Pointer to formatting string +** argList - Open Argument List +** Returns : +** --- - number of characters written, negative for +** error case +** =================================================================== +*/ + +void XF1_Init(void); +/* +** =================================================================== +** Method : Init (component XFormat) +** +** Description : +** Driver initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +void XF1_Deinit(void); +/* +** =================================================================== +** Method : Deinit (component XFormat) +** +** Description : +** Driver de-initialization routine +** Parameters : None +** Returns : Nothing +** =================================================================== +*/ + +/* END XF1. */ + +#endif +/* ifndef __XF1_H */ +/*! +** @} +*/ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1config.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1config.h new file mode 100644 index 0000000..cb73d79 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/XF1config.h @@ -0,0 +1,75 @@ +#ifndef __XF1_CONFIG_H +#define __XF1_CONFIG_H + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_FLOAT 0 /* 1: enable, 0: disable floating format (component property) */ +#endif + + +#ifndef XF1_CONFIG_XCFG_FORMAT_FLOAT + #define XCFG_FORMAT_STATIC /* static */ /* used for the buffer. WARNING: using 'static' makes it non-reentrant! */ +#endif + +/** + * MSVC use in x64 model IL32P64 architecture so the largest integer + * is not a standard C integer. + */ +#if defined(_MSC_VER) && defined(_M_AMD64) +#define LONG long long +#define XCFG_FORMAT_LONG_ARE_LONGLONG +#endif + + +/** + * SDCC support only float and for now do not support long long + */ +#ifdef __SDCC +#define DOUBLE float +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 0 +#endif +#endif + + +/** + * Define internal parameters as volatile for 8 bit cpu define + * XCFG_FORMAT_STATIC=static to reduce stack usage. + */ +#ifndef XCFG_FORMAT_STATIC + #define XCFG_FORMAT_STATIC +#endif + +/** + * Define XCFG_FORMAT_FLOAT=0 to remove floating point support + */ +#ifndef XCFG_FORMAT_FLOAT +#define XCFG_FORMAT_FLOAT 1 +#endif + +/** + * Detect support for va_copy this macro must be called for example + * in x86_64 machine to adjust the stack frame when an argument of va_list + * is passed over functions. + */ +#ifndef XCFG_FORMAT_VA_COPY +#if defined(__GNUC__) && defined(__x86_64__) +#define XCFG_FORMAT_VA_COPY 1 +#endif + + +#ifndef XCFG_FORMAT_VA_COPY +#define XCFG_FORMAT_VA_COPY 0 +#endif + +#endif + + +/** + * Define to 0 to support long long type (prefix ll) + */ +#ifndef XCFG_FORMAT_LONGLONG +#define XCFG_FORMAT_LONGLONG 1 +#endif + + +#endif /* __XF1_CONFIG_H */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.c new file mode 100644 index 0000000..4676b0d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.c @@ -0,0 +1,354 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include "FreeRTOS.h" +#include "task.h" +#include "croutine.h" + +/* Remove the whole file is co-routines are not being used. */ +#if( configUSE_CO_ROUTINES != 0 ) + +/* + * Some kernel aware debuggers require data to be viewed to be global, rather + * than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + + +/* Lists for ready and blocked co-routines. --------------------*/ +static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */ +static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */ +static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */ +static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */ +static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */ +static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */ + +/* Other file private variables. --------------------------------*/ +CRCB_t * pxCurrentCoRoutine = NULL; +static UBaseType_t uxTopCoRoutineReadyPriority = 0; +static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0; + +/* The initial state of the co-routine when it is created. */ +#define corINITIAL_STATE ( 0 ) + +/* + * Place the co-routine represented by pxCRCB into the appropriate ready queue + * for the priority. It is inserted at the end of the list. + * + * This macro accesses the co-routine ready lists and therefore must not be + * used from within an ISR. + */ +#define prvAddCoRoutineToReadyQueue( pxCRCB ) \ +{ \ + if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \ + { \ + uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \ + } \ + vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \ +} + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first co-routine. + */ +static void prvInitialiseCoRoutineLists( void ); + +/* + * Co-routines that are readied by an interrupt cannot be placed directly into + * the ready lists (there is no mutual exclusion). Instead they are placed in + * in the pending ready list in order that they can later be moved to the ready + * list by the co-routine scheduler. + */ +static void prvCheckPendingReadyList( void ); + +/* + * Macro that looks at the list of co-routines that are currently delayed to + * see if any require waking. + * + * Co-routines are stored in the queue in the order of their wake time - + * meaning once one co-routine has been found whose timer has not expired + * we need not look any further down the list. + */ +static void prvCheckDelayedList( void ); + +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ) +{ +BaseType_t xReturn; +CRCB_t *pxCoRoutine; + + /* Allocate the memory that will store the co-routine control block. */ + pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) ); + if( pxCoRoutine ) + { + /* If pxCurrentCoRoutine is NULL then this is the first co-routine to + be created and the co-routine data structures need initialising. */ + if( pxCurrentCoRoutine == NULL ) + { + pxCurrentCoRoutine = pxCoRoutine; + prvInitialiseCoRoutineLists(); + } + + /* Check the priority is within limits. */ + if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES ) + { + uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1; + } + + /* Fill out the co-routine control block from the function parameters. */ + pxCoRoutine->uxState = corINITIAL_STATE; + pxCoRoutine->uxPriority = uxPriority; + pxCoRoutine->uxIndex = uxIndex; + pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode; + + /* Initialise all the other co-routine control block parameters. */ + vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) ); + vListInitialiseItem( &( pxCoRoutine->xEventListItem ) ); + + /* Set the co-routine control block as a link back from the ListItem_t. + This is so we can get back to the containing CRCB from a generic item + in a list. */ + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine ); + listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) ); + + /* Now the co-routine has been initialised it can be added to the ready + list at the correct priority. */ + prvAddCoRoutineToReadyQueue( pxCoRoutine ); + + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ) +{ +TickType_t xTimeToWake; + + /* Calculate the time to wake - this may overflow but this is + not a problem. */ + xTimeToWake = xCoRoutineTickCount + xTicksToDelay; + + /* We must remove ourselves from the ready list before adding + ourselves to the blocked list as the same list item is used for + both lists. */ + ( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake ); + + if( xTimeToWake < xCoRoutineTickCount ) + { + /* Wake time has overflowed. Place this item in the + overflow list. */ + vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + else + { + /* The wake time has not overflowed, so we can use the + current block list. */ + vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) ); + } + + if( pxEventList ) + { + /* Also add the co-routine to an event list. If this is done then the + function must be called with interrupts disabled. */ + vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckPendingReadyList( void ) +{ + /* Are there any co-routines waiting to get moved to the ready list? These + are co-routines that have been readied by an ISR. The ISR cannot access + the ready lists itself. */ + while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE ) + { + CRCB_t *pxUnblockedCRCB; + + /* The pending ready list can be accessed by an ISR. */ + portDISABLE_INTERRUPTS(); + { + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + } + portENABLE_INTERRUPTS(); + + ( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) ); + prvAddCoRoutineToReadyQueue( pxUnblockedCRCB ); + } +} +/*-----------------------------------------------------------*/ + +static void prvCheckDelayedList( void ) +{ +CRCB_t *pxCRCB; + + xPassedTicks = xTaskGetTickCount() - xLastTickCount; + while( xPassedTicks ) + { + xCoRoutineTickCount++; + xPassedTicks--; + + /* If the tick count has overflowed we need to swap the ready lists. */ + if( xCoRoutineTickCount == 0 ) + { + List_t * pxTemp; + + /* Tick count has overflowed so we need to swap the delay lists. If there are + any items in pxDelayedCoRoutineList here then there is an error! */ + pxTemp = pxDelayedCoRoutineList; + pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList; + pxOverflowDelayedCoRoutineList = pxTemp; + } + + /* See if this tick has made a timeout expire. */ + while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE ) + { + pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList ); + + if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) ) + { + /* Timeout not yet expired. */ + break; + } + + portDISABLE_INTERRUPTS(); + { + /* The event could have occurred just before this critical + section. If this is the case then the generic list item will + have been moved to the pending ready list and the following + line is still valid. Also the pvContainer parameter will have + been set to NULL so the following lines are also valid. */ + ( void ) uxListRemove( &( pxCRCB->xGenericListItem ) ); + + /* Is the co-routine waiting on an event also? */ + if( pxCRCB->xEventListItem.pxContainer ) + { + ( void ) uxListRemove( &( pxCRCB->xEventListItem ) ); + } + } + portENABLE_INTERRUPTS(); + + prvAddCoRoutineToReadyQueue( pxCRCB ); + } + } + + xLastTickCount = xCoRoutineTickCount; +} +/*-----------------------------------------------------------*/ + +void vCoRoutineSchedule( void ) +{ + /* See if any co-routines readied by events need moving to the ready lists. */ + prvCheckPendingReadyList(); + + /* See if any delayed co-routines have timed out. */ + prvCheckDelayedList(); + + /* Find the highest priority queue that contains ready co-routines. */ + while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) ) + { + if( uxTopCoRoutineReadyPriority == 0 ) + { + /* No more co-routines to check. */ + return; + } + --uxTopCoRoutineReadyPriority; + } + + /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines + of the same priority get an equal share of the processor time. */ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ); + + /* Call the co-routine. */ + ( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex ); + + return; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseCoRoutineLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ ) + { + vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) ); + } + + vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 ); + vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 ); + vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList ); + + /* Start with pxDelayedCoRoutineList using list1 and the + pxOverflowDelayedCoRoutineList using list2. */ + pxDelayedCoRoutineList = &xDelayedCoRoutineList1; + pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2; +} +/*-----------------------------------------------------------*/ + +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ) +{ +CRCB_t *pxUnblockedCRCB; +BaseType_t xReturn; + + /* This function is called from within an interrupt. It can only access + event lists and the pending ready list. This function assumes that a + check has already been made to ensure pxEventList is not empty. */ + pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); + ( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) ); + vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) ); + + if( pxUnblockedCRCB->uxPriority >= pxCurrentCoRoutine->uxPriority ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} + +#endif /* configUSE_CO_ROUTINES == 0 */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.h new file mode 100644 index 0000000..a98ccad --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/croutine.h @@ -0,0 +1,721 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef CO_ROUTINE_H +#define CO_ROUTINE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include croutine.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to hide the implementation of the co-routine control block. The +control block structure however has to be included in the header due to +the macro implementation of the co-routine functionality. */ +typedef void * CoRoutineHandle_t; + +/* Defines the prototype to which co-routine functions must conform. */ +typedef void (*crCOROUTINE_CODE)( CoRoutineHandle_t, UBaseType_t ); + +typedef struct corCoRoutineControlBlock +{ + crCOROUTINE_CODE pxCoRoutineFunction; + ListItem_t xGenericListItem; /*< List item used to place the CRCB in ready and blocked queues. */ + ListItem_t xEventListItem; /*< List item used to place the CRCB in event lists. */ + UBaseType_t uxPriority; /*< The priority of the co-routine in relation to other co-routines. */ + UBaseType_t uxIndex; /*< Used to distinguish between co-routines when multiple co-routines use the same co-routine function. */ + uint16_t uxState; /*< Used internally by the co-routine implementation. */ +} CRCB_t; /* Co-routine control block. Note must be identical in size down to uxPriority with TCB_t. */ + +/** + * croutine. h + *
+ BaseType_t xCoRoutineCreate(
+                                 crCOROUTINE_CODE pxCoRoutineCode,
+                                 UBaseType_t uxPriority,
+                                 UBaseType_t uxIndex
+                               );
+ * + * Create a new co-routine and add it to the list of co-routines that are + * ready to run. + * + * @param pxCoRoutineCode Pointer to the co-routine function. Co-routine + * functions require special syntax - see the co-routine section of the WEB + * documentation for more information. + * + * @param uxPriority The priority with respect to other co-routines at which + * the co-routine will run. + * + * @param uxIndex Used to distinguish between different co-routines that + * execute the same function. See the example below and the co-routine section + * of the WEB documentation for further information. + * + * @return pdPASS if the co-routine was successfully created and added to a ready + * list, otherwise an error code defined with ProjDefs.h. + * + * Example usage: +
+ // Co-routine to be created.
+ void vFlashCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ static const char cLedToFlash[ 2 ] = { 5, 6 };
+ static const TickType_t uxFlashRates[ 2 ] = { 200, 400 };
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // This co-routine just delays for a fixed period, then toggles
+         // an LED.  Two co-routines are created using this function, so
+         // the uxIndex parameter is used to tell the co-routine which
+         // LED to flash and how int32_t to delay.  This assumes xQueue has
+         // already been created.
+         vParTestToggleLED( cLedToFlash[ uxIndex ] );
+         crDELAY( xHandle, uxFlashRates[ uxIndex ] );
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+
+ // Function that creates two co-routines.
+ void vOtherFunction( void )
+ {
+ uint8_t ucParameterToPass;
+ TaskHandle_t xHandle;
+
+     // Create two co-routines at priority 0.  The first is given index 0
+     // so (from the code above) toggles LED 5 every 200 ticks.  The second
+     // is given index 1 so toggles LED 6 every 400 ticks.
+     for( uxIndex = 0; uxIndex < 2; uxIndex++ )
+     {
+         xCoRoutineCreate( vFlashCoRoutine, 0, uxIndex );
+     }
+ }
+   
+ * \defgroup xCoRoutineCreate xCoRoutineCreate + * \ingroup Tasks + */ +BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex ); + + +/** + * croutine. h + *
+ void vCoRoutineSchedule( void );
+ * + * Run a co-routine. + * + * vCoRoutineSchedule() executes the highest priority co-routine that is able + * to run. The co-routine will execute until it either blocks, yields or is + * preempted by a task. Co-routines execute cooperatively so one + * co-routine cannot be preempted by another, but can be preempted by a task. + * + * If an application comprises of both tasks and co-routines then + * vCoRoutineSchedule should be called from the idle task (in an idle task + * hook). + * + * Example usage: +
+ // This idle task hook will schedule a co-routine each time it is called.
+ // The rest of the idle task will execute between co-routine calls.
+ void vApplicationIdleHook( void )
+ {
+	vCoRoutineSchedule();
+ }
+
+ // Alternatively, if you do not require any other part of the idle task to
+ // execute, the idle task hook can call vCoRoutineScheduler() within an
+ // infinite loop.
+ void vApplicationIdleHook( void )
+ {
+    for( ;; )
+    {
+        vCoRoutineSchedule();
+    }
+ }
+ 
+ * \defgroup vCoRoutineSchedule vCoRoutineSchedule + * \ingroup Tasks + */ +void vCoRoutineSchedule( void ); + +/** + * croutine. h + *
+ crSTART( CoRoutineHandle_t xHandle );
+ * + * This macro MUST always be called at the start of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crSTART( pxCRCB ) switch( ( ( CRCB_t * )( pxCRCB ) )->uxState ) { case 0: + +/** + * croutine. h + *
+ crEND();
+ * + * This macro MUST always be called at the end of a co-routine function. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static int32_t ulAVariable;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+          // Co-routine functionality goes here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crSTART crSTART + * \ingroup Tasks + */ +#define crEND() } + +/* + * These macros are intended for internal use by the co-routine implementation + * only. The macros should not be used directly by application writers. + */ +#define crSET_STATE0( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = (__LINE__ * 2); return; case (__LINE__ * 2): +#define crSET_STATE1( xHandle ) ( ( CRCB_t * )( xHandle ) )->uxState = ((__LINE__ * 2)+1); return; case ((__LINE__ * 2)+1): + +/** + * croutine. h + *
+ crDELAY( CoRoutineHandle_t xHandle, TickType_t xTicksToDelay );
+ * + * Delay a co-routine for a fixed period of time. + * + * crDELAY can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * @param xHandle The handle of the co-routine to delay. This is the xHandle + * parameter of the co-routine function. + * + * @param xTickToDelay The number of ticks that the co-routine should delay + * for. The actual amount of time this equates to is defined by + * configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant portTICK_PERIOD_MS + * can be used to convert ticks to milliseconds. + * + * Example usage: +
+ // Co-routine to be created.
+ void vACoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ // This may not be necessary for const variables.
+ // We are to delay for 200ms.
+ static const xTickType xDelayTime = 200 / portTICK_PERIOD_MS;
+
+     // Must start every co-routine with a call to crSTART();
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+        // Delay for 200ms.
+        crDELAY( xHandle, xDelayTime );
+
+        // Do something here.
+     }
+
+     // Must end every co-routine with a call to crEND();
+     crEND();
+ }
+ * \defgroup crDELAY crDELAY + * \ingroup Tasks + */ +#define crDELAY( xHandle, xTicksToDelay ) \ + if( ( xTicksToDelay ) > 0 ) \ + { \ + vCoRoutineAddToDelayedList( ( xTicksToDelay ), NULL ); \ + } \ + crSET_STATE0( ( xHandle ) ); + +/** + *
+ crQUEUE_SEND(
+                  CoRoutineHandle_t xHandle,
+                  QueueHandle_t pxQueue,
+                  void *pvItemToQueue,
+                  TickType_t xTicksToWait,
+                  BaseType_t *pxResult
+             )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_SEND can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue on which the data will be posted. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvItemToQueue A pointer to the data being posted onto the queue. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied from pvItemToQueue into the queue + * itself. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for space to become available on the queue, should space not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see example + * below). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully posted onto the queue, otherwise it will be set to an + * error defined within ProjDefs.h. + * + * Example usage: +
+ // Co-routine function that blocks for a fixed period then posts a number onto
+ // a queue.
+ static void prvCoRoutineFlashTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xNumberToPost = 0;
+ static BaseType_t xResult;
+
+    // Co-routines must begin with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // This assumes the queue has already been created.
+        crQUEUE_SEND( xHandle, xCoRoutineQueue, &xNumberToPost, NO_DELAY, &xResult );
+
+        if( xResult != pdPASS )
+        {
+            // The message was not posted!
+        }
+
+        // Increment the number to be posted onto the queue.
+        xNumberToPost++;
+
+        // Delay for 100 ticks.
+        crDELAY( xHandle, 100 );
+    }
+
+    // Co-routines must end with a call to crEND().
+    crEND();
+ }
+ * \defgroup crQUEUE_SEND crQUEUE_SEND + * \ingroup Tasks + */ +#define crQUEUE_SEND( xHandle, pxQueue, pvItemToQueue, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRSend( ( pxQueue) , ( pvItemToQueue) , ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *pxResult = xQueueCRSend( ( pxQueue ), ( pvItemToQueue ), 0 ); \ + } \ + if( *pxResult == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *pxResult = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_RECEIVE(
+                     CoRoutineHandle_t xHandle,
+                     QueueHandle_t pxQueue,
+                     void *pvBuffer,
+                     TickType_t xTicksToWait,
+                     BaseType_t *pxResult
+                 )
+ * + * The macro's crQUEUE_SEND() and crQUEUE_RECEIVE() are the co-routine + * equivalent to the xQueueSend() and xQueueReceive() functions used by tasks. + * + * crQUEUE_SEND and crQUEUE_RECEIVE can only be used from a co-routine whereas + * xQueueSend() and xQueueReceive() can only be used from tasks. + * + * crQUEUE_RECEIVE can only be called from the co-routine function itself - not + * from within a function called by the co-routine function. This is because + * co-routines do not maintain their own stack. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xHandle The handle of the calling co-routine. This is the xHandle + * parameter of the co-routine function. + * + * @param pxQueue The handle of the queue from which the data will be received. + * The handle is obtained as the return value when the queue is created using + * the xQueueCreate() API function. + * + * @param pvBuffer The buffer into which the received item is to be copied. + * The number of bytes of each queued item is specified when the queue is + * created. This number of bytes is copied into pvBuffer. + * + * @param xTickToDelay The number of ticks that the co-routine should block + * to wait for data to become available from the queue, should data not be + * available immediately. The actual amount of time this equates to is defined + * by configTICK_RATE_HZ (set in FreeRTOSConfig.h). The constant + * portTICK_PERIOD_MS can be used to convert ticks to milliseconds (see the + * crQUEUE_SEND example). + * + * @param pxResult The variable pointed to by pxResult will be set to pdPASS if + * data was successfully retrieved from the queue, otherwise it will be set to + * an error code as defined within ProjDefs.h. + * + * Example usage: +
+ // A co-routine receives the number of an LED to flash from a queue.  It
+ // blocks on the queue until the number is received.
+ static void prvCoRoutineFlashWorkTask( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // Variables in co-routines must be declared static if they must maintain value across a blocking call.
+ static BaseType_t xResult;
+ static UBaseType_t uxLEDToFlash;
+
+    // All co-routines must start with a call to crSTART().
+    crSTART( xHandle );
+
+    for( ;; )
+    {
+        // Wait for data to become available on the queue.
+        crQUEUE_RECEIVE( xHandle, xCoRoutineQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+        if( xResult == pdPASS )
+        {
+            // We received the LED to flash - flash it!
+            vParTestToggleLED( uxLEDToFlash );
+        }
+    }
+
+    crEND();
+ }
+ * \defgroup crQUEUE_RECEIVE crQUEUE_RECEIVE + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE( xHandle, pxQueue, pvBuffer, xTicksToWait, pxResult ) \ +{ \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), ( xTicksToWait ) ); \ + if( *( pxResult ) == errQUEUE_BLOCKED ) \ + { \ + crSET_STATE0( ( xHandle ) ); \ + *( pxResult ) = xQueueCRReceive( ( pxQueue) , ( pvBuffer ), 0 ); \ + } \ + if( *( pxResult ) == errQUEUE_YIELD ) \ + { \ + crSET_STATE1( ( xHandle ) ); \ + *( pxResult ) = pdPASS; \ + } \ +} + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvItemToQueue,
+                            BaseType_t xCoRoutinePreviouslyWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_SEND_FROM_ISR can only be called from an ISR to send data to a queue + * that is being used from within a co-routine. + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xCoRoutinePreviouslyWoken This is included so an ISR can post onto + * the same queue multiple times from a single interrupt. The first call + * should always pass in pdFALSE. Subsequent calls should pass in + * the value returned from the previous call. + * + * @return pdTRUE if a co-routine was woken by posting onto the queue. This is + * used by the ISR to determine if a context switch may be required following + * the ISR. + * + * Example usage: +
+ // A co-routine that blocks on a queue waiting for characters to be received.
+ static void vReceivingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ char cRxedChar;
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Wait for data to become available on the queue.  This assumes the
+         // queue xCommsRxQueue has already been created!
+         crQUEUE_RECEIVE( xHandle, xCommsRxQueue, &uxLEDToFlash, portMAX_DELAY, &xResult );
+
+         // Was a character received?
+         if( xResult == pdPASS )
+         {
+             // Process the character here.
+         }
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to send characters received on a serial port to
+ // a co-routine.
+ void vUART_ISR( void )
+ {
+ char cRxedChar;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     // We loop around reading characters until there are none left in the UART.
+     while( UART_RX_REG_NOT_EMPTY() )
+     {
+         // Obtain the character from the UART.
+         cRxedChar = UART_RX_REG;
+
+         // Post the character onto a queue.  xCRWokenByPost will be pdFALSE
+         // the first time around the loop.  If the post causes a co-routine
+         // to be woken (unblocked) then xCRWokenByPost will be set to pdTRUE.
+         // In this manner we can ensure that if more than one co-routine is
+         // blocked on the queue only one is woken by this ISR no matter how
+         // many characters are posted to the queue.
+         xCRWokenByPost = crQUEUE_SEND_FROM_ISR( xCommsRxQueue, &cRxedChar, xCRWokenByPost );
+     }
+ }
+ * \defgroup crQUEUE_SEND_FROM_ISR crQUEUE_SEND_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_SEND_FROM_ISR( pxQueue, pvItemToQueue, xCoRoutinePreviouslyWoken ) xQueueCRSendFromISR( ( pxQueue ), ( pvItemToQueue ), ( xCoRoutinePreviouslyWoken ) ) + + +/** + * croutine. h + *
+  crQUEUE_SEND_FROM_ISR(
+                            QueueHandle_t pxQueue,
+                            void *pvBuffer,
+                            BaseType_t * pxCoRoutineWoken
+                       )
+ * + * The macro's crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() are the + * co-routine equivalent to the xQueueSendFromISR() and xQueueReceiveFromISR() + * functions used by tasks. + * + * crQUEUE_SEND_FROM_ISR() and crQUEUE_RECEIVE_FROM_ISR() can only be used to + * pass data between a co-routine and and ISR, whereas xQueueSendFromISR() and + * xQueueReceiveFromISR() can only be used to pass data between a task and and + * ISR. + * + * crQUEUE_RECEIVE_FROM_ISR can only be called from an ISR to receive data + * from a queue that is being used from within a co-routine (a co-routine + * posted to the queue). + * + * See the co-routine section of the WEB documentation for information on + * passing data between tasks and co-routines and between ISR's and + * co-routines. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvBuffer A pointer to a buffer into which the received item will be + * placed. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from the queue into + * pvBuffer. + * + * @param pxCoRoutineWoken A co-routine may be blocked waiting for space to become + * available on the queue. If crQUEUE_RECEIVE_FROM_ISR causes such a + * co-routine to unblock *pxCoRoutineWoken will get set to pdTRUE, otherwise + * *pxCoRoutineWoken will remain unchanged. + * + * @return pdTRUE an item was successfully received from the queue, otherwise + * pdFALSE. + * + * Example usage: +
+ // A co-routine that posts a character to a queue then blocks for a fixed
+ // period.  The character is incremented each time.
+ static void vSendingCoRoutine( CoRoutineHandle_t xHandle, UBaseType_t uxIndex )
+ {
+ // cChar holds its value while this co-routine is blocked and must therefore
+ // be declared static.
+ static char cCharToTx = 'a';
+ BaseType_t xResult;
+
+     // All co-routines must start with a call to crSTART().
+     crSTART( xHandle );
+
+     for( ;; )
+     {
+         // Send the next character to the queue.
+         crQUEUE_SEND( xHandle, xCoRoutineQueue, &cCharToTx, NO_DELAY, &xResult );
+
+         if( xResult == pdPASS )
+         {
+             // The character was successfully posted to the queue.
+         }
+		 else
+		 {
+			// Could not post the character to the queue.
+		 }
+
+         // Enable the UART Tx interrupt to cause an interrupt in this
+		 // hypothetical UART.  The interrupt will obtain the character
+		 // from the queue and send it.
+		 ENABLE_RX_INTERRUPT();
+
+		 // Increment to the next character then block for a fixed period.
+		 // cCharToTx will maintain its value across the delay as it is
+		 // declared static.
+		 cCharToTx++;
+		 if( cCharToTx > 'x' )
+		 {
+			cCharToTx = 'a';
+		 }
+		 crDELAY( 100 );
+     }
+
+     // All co-routines must end with a call to crEND().
+     crEND();
+ }
+
+ // An ISR that uses a queue to receive characters to send on a UART.
+ void vUART_ISR( void )
+ {
+ char cCharToTx;
+ BaseType_t xCRWokenByPost = pdFALSE;
+
+     while( UART_TX_REG_EMPTY() )
+     {
+         // Are there any characters in the queue waiting to be sent?
+		 // xCRWokenByPost will automatically be set to pdTRUE if a co-routine
+		 // is woken by the post - ensuring that only a single co-routine is
+		 // woken no matter how many times we go around this loop.
+         if( crQUEUE_RECEIVE_FROM_ISR( pxQueue, &cCharToTx, &xCRWokenByPost ) )
+		 {
+			 SEND_CHARACTER( cCharToTx );
+		 }
+     }
+ }
+ * \defgroup crQUEUE_RECEIVE_FROM_ISR crQUEUE_RECEIVE_FROM_ISR + * \ingroup Tasks + */ +#define crQUEUE_RECEIVE_FROM_ISR( pxQueue, pvBuffer, pxCoRoutineWoken ) xQueueCRReceiveFromISR( ( pxQueue ), ( pvBuffer ), ( pxCoRoutineWoken ) ) + +/* + * This function is intended for internal use by the co-routine macros only. + * The macro nature of the co-routine implementation requires that the + * prototype appears here. The function should not be used by application + * writers. + * + * Removes the current co-routine from its ready list and places it in the + * appropriate delayed list. + */ +void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList ); + +/* + * This function is intended for internal use by the queue implementation only. + * The function should not be used by application writers. + * + * Removes the highest priority co-routine from the event list and places it in + * the pending ready list. + */ +BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList ); + +#ifdef __cplusplus +} +#endif + +#endif /* CO_ROUTINE_H */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/deprecated_definitions.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/deprecated_definitions.h new file mode 100644 index 0000000..d869789 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/deprecated_definitions.h @@ -0,0 +1,280 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef DEPRECATED_DEFINITIONS_H +#define DEPRECATED_DEFINITIONS_H + + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. The +definitions below remain in the code for backward compatibility only. New +projects should not use them. */ + +#ifdef OPEN_WATCOM_INDUSTRIAL_PC_PORT + #include "..\..\Source\portable\owatcom\16bitdos\pc\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef OPEN_WATCOM_FLASH_LITE_186_PORT + #include "..\..\Source\portable\owatcom\16bitdos\flsh186\portmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef GCC_MEGA_AVR + #include "../portable/GCC/ATMega323/portmacro.h" +#endif + +#ifdef IAR_MEGA_AVR + #include "../portable/IAR/ATMega323/portmacro.h" +#endif + +#ifdef MPLAB_PIC24_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_DSPIC_PORT + #include "../../Source/portable/MPLAB/PIC24_dsPIC/portmacro.h" +#endif + +#ifdef MPLAB_PIC18F_PORT + #include "../../Source/portable/MPLAB/PIC18F/portmacro.h" +#endif + +#ifdef MPLAB_PIC32MX_PORT + #include "../../Source/portable/MPLAB/PIC32MX/portmacro.h" +#endif + +#ifdef _FEDPICC + #include "libFreeRTOS/Include/portmacro.h" +#endif + +#ifdef SDCC_CYGNAL + #include "../../Source/portable/SDCC/Cygnal/portmacro.h" +#endif + +#ifdef GCC_ARM7 + #include "../../Source/portable/GCC/ARM7_LPC2000/portmacro.h" +#endif + +#ifdef GCC_ARM7_ECLIPSE + #include "portmacro.h" +#endif + +#ifdef ROWLEY_LPC23xx + #include "../../Source/portable/GCC/ARM7_LPC23xx/portmacro.h" +#endif + +#ifdef IAR_MSP430 + #include "..\..\Source\portable\IAR\MSP430\portmacro.h" +#endif + +#ifdef GCC_MSP430 + #include "../../Source/portable/GCC/MSP430F449/portmacro.h" +#endif + +#ifdef ROWLEY_MSP430 + #include "../../Source/portable/Rowley/MSP430F449/portmacro.h" +#endif + +#ifdef ARM7_LPC21xx_KEIL_RVDS + #include "..\..\Source\portable\RVDS\ARM7_LPC21xx\portmacro.h" +#endif + +#ifdef SAM7_GCC + #include "../../Source/portable/GCC/ARM7_AT91SAM7S/portmacro.h" +#endif + +#ifdef SAM7_IAR + #include "..\..\Source\portable\IAR\AtmelSAM7S64\portmacro.h" +#endif + +#ifdef SAM9XE_IAR + #include "..\..\Source\portable\IAR\AtmelSAM9XE\portmacro.h" +#endif + +#ifdef LPC2000_IAR + #include "..\..\Source\portable\IAR\LPC2000\portmacro.h" +#endif + +#ifdef STR71X_IAR + #include "..\..\Source\portable\IAR\STR71x\portmacro.h" +#endif + +#ifdef STR75X_IAR + #include "..\..\Source\portable\IAR\STR75x\portmacro.h" +#endif + +#ifdef STR75X_GCC + #include "..\..\Source\portable\GCC\STR75x\portmacro.h" +#endif + +#ifdef STR91X_IAR + #include "..\..\Source\portable\IAR\STR91x\portmacro.h" +#endif + +#ifdef GCC_H8S + #include "../../Source/portable/GCC/H8S2329/portmacro.h" +#endif + +#ifdef GCC_AT91FR40008 + #include "../../Source/portable/GCC/ARM7_AT91FR40008/portmacro.h" +#endif + +#ifdef RVDS_ARMCM3_LM3S102 + #include "../../Source/portable/RVDS/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3_LM3S102 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef GCC_ARMCM3 + #include "../../Source/portable/GCC/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARM_CM3 + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef IAR_ARMCM3_LM + #include "../../Source/portable/IAR/ARM_CM3/portmacro.h" +#endif + +#ifdef HCS12_CODE_WARRIOR + #include "../../Source/portable/CodeWarrior/HCS12/portmacro.h" +#endif + +#ifdef MICROBLAZE_GCC + #include "../../Source/portable/GCC/MicroBlaze/portmacro.h" +#endif + +#ifdef TERN_EE + #include "..\..\Source\portable\Paradigm\Tern_EE\small\portmacro.h" +#endif + +#ifdef GCC_HCS12 + #include "../../Source/portable/GCC/HCS12/portmacro.h" +#endif + +#ifdef GCC_MCF5235 + #include "../../Source/portable/GCC/MCF5235/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_GCC + #include "../../../Source/portable/GCC/ColdFire_V2/portmacro.h" +#endif + +#ifdef COLDFIRE_V2_CODEWARRIOR + #include "../../Source/portable/CodeWarrior/ColdFire_V2/portmacro.h" +#endif + +#ifdef GCC_PPC405 + #include "../../Source/portable/GCC/PPC405_Xilinx/portmacro.h" +#endif + +#ifdef GCC_PPC440 + #include "../../Source/portable/GCC/PPC440_Xilinx/portmacro.h" +#endif + +#ifdef _16FX_SOFTUNE + #include "..\..\Source\portable\Softune\MB96340\portmacro.h" +#endif + +#ifdef BCC_INDUSTRIAL_PC_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\PC\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef BCC_FLASH_LITE_186_PORT + /* A short file name has to be used in place of the normal + FreeRTOSConfig.h when using the Borland compiler. */ + #include "frconfig.h" + #include "..\portable\BCC\16BitDOS\flsh186\prtmacro.h" + typedef void ( __interrupt __far *pxISR )(); +#endif + +#ifdef __GNUC__ + #ifdef __AVR32_AVR32A__ + #include "portmacro.h" + #endif +#endif + +#ifdef __ICCAVR32__ + #ifdef __CORE__ + #if __CORE__ == __AVR32A__ + #include "portmacro.h" + #endif + #endif +#endif + +#ifdef __91467D + #include "portmacro.h" +#endif + +#ifdef __96340 + #include "portmacro.h" +#endif + + +#ifdef __IAR_V850ES_Fx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx3_L__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Jx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_V850ES_Hx2__ + #include "../../Source/portable/IAR/V850ES/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#ifdef __IAR_78K0R_Kx3L__ + #include "../../Source/portable/IAR/78K0R/portmacro.h" +#endif + +#endif /* DEPRECATED_DEFINITIONS_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.c new file mode 100644 index 0000000..692288f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.c @@ -0,0 +1,754 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "event_groups.h" + +/* Lint e961, e750 and e9021 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021 See comment above. */ + +/* The following bit fields convey control information in a task's event list +item value. It is important they don't clash with the +taskEVENT_LIST_ITEM_VALUE_IN_USE definition. */ +#if configUSE_16_BIT_TICKS == 1 + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x0100U + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x0200U + #define eventWAIT_FOR_ALL_BITS 0x0400U + #define eventEVENT_BITS_CONTROL_BYTES 0xff00U +#else + #define eventCLEAR_EVENTS_ON_EXIT_BIT 0x01000000UL + #define eventUNBLOCKED_DUE_TO_BIT_SET 0x02000000UL + #define eventWAIT_FOR_ALL_BITS 0x04000000UL + #define eventEVENT_BITS_CONTROL_BYTES 0xff000000UL +#endif + +typedef struct EventGroupDef_t +{ + EventBits_t uxEventBits; + List_t xTasksWaitingForBits; /*< List of tasks waiting for a bit to be set. */ + + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxEventGroupNumber; + #endif + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the event group is statically allocated to ensure no attempt is made to free the memory. */ + #endif +} EventGroup_t; + +/*-----------------------------------------------------------*/ + +/* + * Test the bits set in uxCurrentEventBits to see if the wait condition is met. + * The wait condition is defined by xWaitForAllBits. If xWaitForAllBits is + * pdTRUE then the wait condition is met if all the bits set in uxBitsToWaitFor + * are also set in uxCurrentEventBits. If xWaitForAllBits is pdFALSE then the + * wait condition is met if any of the bits set in uxBitsToWait for are also set + * in uxCurrentEventBits. + */ +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) + { + EventGroup_t *pxEventBits; + + /* A StaticEventGroup_t object must be provided. */ + configASSERT( pxEventGroupBuffer ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticEventGroup_t equals the size of the real + event group structure. */ + volatile size_t xSize = sizeof( StaticEventGroup_t ); + configASSERT( xSize == sizeof( EventGroup_t ) ); + } /*lint !e529 xSize is referenced if configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + /* The user has provided a statically allocated event group - use it. */ + pxEventBits = ( EventGroup_t * ) pxEventGroupBuffer; /*lint !e740 !e9087 EventGroup_t and StaticEventGroup_t are deliberately aliased for data hiding purposes and guaranteed to have the same size and alignment requirement - checked by configASSERT(). */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note that + this event group was created statically in case the event group + is later deleted. */ + pxEventBits->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + /* xEventGroupCreateStatic should only ever be called with + pxEventGroupBuffer pointing to a pre-allocated (compile time + allocated) StaticEventGroup_t variable. */ + traceEVENT_GROUP_CREATE_FAILED(); + } + + return pxEventBits; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + EventGroupHandle_t xEventGroupCreate( void ) + { + EventGroup_t *pxEventBits; + + /* Allocate the event group. Justification for MISRA deviation as + follows: pvPortMalloc() always ensures returned memory blocks are + aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the EventGroup_t structure - which (if you + follow it through) is the alignment requirements of the TickType_t type + (EventBits_t being of TickType_t itself). Therefore, whenever the + stack alignment requirements are greater than or equal to the + TickType_t alignment requirements the cast is safe. In other cases, + where the natural word size of the architecture is less than + sizeof( TickType_t ), the TickType_t variables will be accessed in two + or more reads operations, and the alignment requirements is only that + of each individual read. */ + pxEventBits = ( EventGroup_t * ) pvPortMalloc( sizeof( EventGroup_t ) ); /*lint !e9087 !e9079 see comment above. */ + + if( pxEventBits != NULL ) + { + pxEventBits->uxEventBits = 0; + vListInitialise( &( pxEventBits->xTasksWaitingForBits ) ); + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Both static and dynamic allocation can be used, so note this + event group was allocated statically in case the event group is + later deleted. */ + pxEventBits->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + traceEVENT_GROUP_CREATE( pxEventBits ); + } + else + { + traceEVENT_GROUP_CREATE_FAILED(); /*lint !e9063 Else branch only exists to allow tracing and does not generate code if trace macros are not defined. */ + } + + return pxEventBits; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) +{ +EventBits_t uxOriginalBitValue, uxReturn; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + uxOriginalBitValue = pxEventBits->uxEventBits; + + ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet ); + + if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + /* All the rendezvous bits are now set - no need to block. */ + uxReturn = ( uxOriginalBitValue | uxBitsToSet ); + + /* Rendezvous always clear the bits. They will have been cleared + already unless this is the only task in the rendezvous. */ + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + + xTicksToWait = 0; + } + else + { + if( xTicksToWait != ( TickType_t ) 0 ) + { + traceEVENT_GROUP_SYNC_BLOCK( xEventGroup, uxBitsToSet, uxBitsToWaitFor ); + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | eventCLEAR_EVENTS_ON_EXIT_BIT | eventWAIT_FOR_ALL_BITS ), xTicksToWait ); + + /* This assignment is obsolete as uxReturn will get set after + the task unblocks, but some compilers mistakenly generate a + warning about uxReturn being returned without being set if the + assignment is omitted. */ + uxReturn = 0; + } + else + { + /* The rendezvous bits were not set, but no block time was + specified - just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + xTimeoutOccurred = pdTRUE; + } + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + /* The task timed out, just return the current event bit value. */ + taskENTER_CRITICAL(); + { + uxReturn = pxEventBits->uxEventBits; + + /* Although the task got here because it timed out before the + bits it was waiting for were set, it is possible that since it + unblocked another task has set the bits. If this is the case + then it needs to clear the bits before exiting. */ + if( ( uxReturn & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* Control bits might be set as the task had blocked should not be + returned. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + + traceEVENT_GROUP_SYNC_END( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn, uxControlBits = 0; +BaseType_t xWaitConditionMet, xAlreadyYielded; +BaseType_t xTimeoutOccurred = pdFALSE; + + /* Check the user is not attempting to wait on the bits used by the kernel + itself, and that at least one bit is being requested. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + configASSERT( uxBitsToWaitFor != 0 ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + vTaskSuspendAll(); + { + const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; + + /* Check to see if the wait condition is already met or not. */ + xWaitConditionMet = prvTestWaitCondition( uxCurrentEventBits, uxBitsToWaitFor, xWaitForAllBits ); + + if( xWaitConditionMet != pdFALSE ) + { + /* The wait condition has already been met so there is no need to + block. */ + uxReturn = uxCurrentEventBits; + xTicksToWait = ( TickType_t ) 0; + + /* Clear the wait bits if requested to do so. */ + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The wait condition has not been met, but no block time was + specified, so just return the current value. */ + uxReturn = uxCurrentEventBits; + xTimeoutOccurred = pdTRUE; + } + else + { + /* The task is going to block to wait for its required bits to be + set. uxControlBits are used to remember the specified behaviour of + this call to xEventGroupWaitBits() - for use when the event bits + unblock the task. */ + if( xClearOnExit != pdFALSE ) + { + uxControlBits |= eventCLEAR_EVENTS_ON_EXIT_BIT; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xWaitForAllBits != pdFALSE ) + { + uxControlBits |= eventWAIT_FOR_ALL_BITS; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the bits that the calling task is waiting for in the + task's event list item so the kernel knows when a match is + found. Then enter the blocked state. */ + vTaskPlaceOnUnorderedEventList( &( pxEventBits->xTasksWaitingForBits ), ( uxBitsToWaitFor | uxControlBits ), xTicksToWait ); + + /* This is obsolete as it will get set after the task unblocks, but + some compilers mistakenly generate a warning about the variable + being returned without being set if it is not done. */ + uxReturn = 0; + + traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); + } + } + xAlreadyYielded = xTaskResumeAll(); + + if( xTicksToWait != ( TickType_t ) 0 ) + { + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The task blocked to wait for its required bits to be set - at this + point either the required bits were set or the block time expired. If + the required bits were set they will have been stored in the task's + event list item, and they should now be retrieved then cleared. */ + uxReturn = uxTaskResetEventItemValue(); + + if( ( uxReturn & eventUNBLOCKED_DUE_TO_BIT_SET ) == ( EventBits_t ) 0 ) + { + taskENTER_CRITICAL(); + { + /* The task timed out, just return the current event bit value. */ + uxReturn = pxEventBits->uxEventBits; + + /* It is possible that the event bits were updated between this + task leaving the Blocked state and running again. */ + if( prvTestWaitCondition( uxReturn, uxBitsToWaitFor, xWaitForAllBits ) != pdFALSE ) + { + if( xClearOnExit != pdFALSE ) + { + pxEventBits->uxEventBits &= ~uxBitsToWaitFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + xTimeoutOccurred = pdTRUE; + } + taskEXIT_CRITICAL(); + } + else + { + /* The task unblocked because the bits were set. */ + } + + /* The task blocked so control bits may have been set. */ + uxReturn &= ~eventEVENT_BITS_CONTROL_BYTES; + } + traceEVENT_GROUP_WAIT_BITS_END( xEventGroup, uxBitsToWaitFor, xTimeoutOccurred ); + + /* Prevent compiler warnings when trace macros are not used. */ + ( void ) xTimeoutOccurred; + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) +{ +EventGroup_t *pxEventBits = xEventGroup; +EventBits_t uxReturn; + + /* Check the user is not attempting to clear the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToClear & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + taskENTER_CRITICAL(); + { + traceEVENT_GROUP_CLEAR_BITS( xEventGroup, uxBitsToClear ); + + /* The value returned is the event group value prior to the bits being + cleared. */ + uxReturn = pxEventBits->uxEventBits; + + /* Clear the bits. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_CLEAR_BITS_FROM_ISR( xEventGroup, uxBitsToClear ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) +{ +UBaseType_t uxSavedInterruptStatus; +EventGroup_t const * const pxEventBits = xEventGroup; +EventBits_t uxReturn; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + uxReturn = pxEventBits->uxEventBits; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return uxReturn; +} /*lint !e818 EventGroupHandle_t is a typedef used in other functions to so can't be pointer to const. */ +/*-----------------------------------------------------------*/ + +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) +{ +ListItem_t *pxListItem, *pxNext; +ListItem_t const *pxListEnd; +List_t const * pxList; +EventBits_t uxBitsToClear = 0, uxBitsWaitedFor, uxControlBits; +EventGroup_t *pxEventBits = xEventGroup; +BaseType_t xMatchFound = pdFALSE; + + /* Check the user is not attempting to set the bits used by the kernel + itself. */ + configASSERT( xEventGroup ); + configASSERT( ( uxBitsToSet & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); + + pxList = &( pxEventBits->xTasksWaitingForBits ); + pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + vTaskSuspendAll(); + { + traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); + + pxListItem = listGET_HEAD_ENTRY( pxList ); + + /* Set the bits. */ + pxEventBits->uxEventBits |= uxBitsToSet; + + /* See if the new bit value should unblock any tasks. */ + while( pxListItem != pxListEnd ) + { + pxNext = listGET_NEXT( pxListItem ); + uxBitsWaitedFor = listGET_LIST_ITEM_VALUE( pxListItem ); + xMatchFound = pdFALSE; + + /* Split the bits waited for from the control bits. */ + uxControlBits = uxBitsWaitedFor & eventEVENT_BITS_CONTROL_BYTES; + uxBitsWaitedFor &= ~eventEVENT_BITS_CONTROL_BYTES; + + if( ( uxControlBits & eventWAIT_FOR_ALL_BITS ) == ( EventBits_t ) 0 ) + { + /* Just looking for single bit being set. */ + if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) != ( EventBits_t ) 0 ) + { + xMatchFound = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( ( uxBitsWaitedFor & pxEventBits->uxEventBits ) == uxBitsWaitedFor ) + { + /* All bits are set. */ + xMatchFound = pdTRUE; + } + else + { + /* Need all bits to be set, but not all the bits were set. */ + } + + if( xMatchFound != pdFALSE ) + { + /* The bits match. Should the bits be cleared on exit? */ + if( ( uxControlBits & eventCLEAR_EVENTS_ON_EXIT_BIT ) != ( EventBits_t ) 0 ) + { + uxBitsToClear |= uxBitsWaitedFor; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Store the actual event flag value in the task's event list + item before removing the task from the event list. The + eventUNBLOCKED_DUE_TO_BIT_SET bit is set so the task knows + that is was unblocked due to its required bits matching, rather + than because it timed out. */ + vTaskRemoveFromUnorderedEventList( pxListItem, pxEventBits->uxEventBits | eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + /* Move onto the next list item. Note pxListItem->pxNext is not + used here as the list item may have been removed from the event list + and inserted into the ready/pending reading list. */ + pxListItem = pxNext; + } + + /* Clear any bits that matched when the eventCLEAR_EVENTS_ON_EXIT_BIT + bit was set in the control word. */ + pxEventBits->uxEventBits &= ~uxBitsToClear; + } + ( void ) xTaskResumeAll(); + + return pxEventBits->uxEventBits; +} +/*-----------------------------------------------------------*/ + +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) +{ +EventGroup_t *pxEventBits = xEventGroup; +const List_t *pxTasksWaitingForBits = &( pxEventBits->xTasksWaitingForBits ); + + vTaskSuspendAll(); + { + traceEVENT_GROUP_DELETE( xEventGroup ); + + while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) + { + /* Unblock the task, returning 0 as the event list is being deleted + and cannot therefore have any bits set. */ + configASSERT( pxTasksWaitingForBits->xListEnd.pxNext != ( const ListItem_t * ) &( pxTasksWaitingForBits->xListEnd ) ); + vTaskRemoveFromUnorderedEventList( pxTasksWaitingForBits->xListEnd.pxNext, eventUNBLOCKED_DUE_TO_BIT_SET ); + } + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The event group can only have been allocated dynamically - free + it again. */ + vPortFree( pxEventBits ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The event group could have been allocated statically or + dynamically, so check before attempting to free the memory. */ + if( pxEventBits->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxEventBits ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + ( void ) xTaskResumeAll(); +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'set bits' command that was pended from +an interrupt. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) +{ + ( void ) xEventGroupSetBits( pvEventGroup, ( EventBits_t ) ulBitsToSet ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +/* For internal use only - execute a 'clear bits' command that was pended from +an interrupt. */ +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) +{ + ( void ) xEventGroupClearBits( pvEventGroup, ( EventBits_t ) ulBitsToClear ); /*lint !e9079 Can't avoid cast to void* as a generic timer callback prototype. Callback casts back to original type so safe. */ +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvTestWaitCondition( const EventBits_t uxCurrentEventBits, const EventBits_t uxBitsToWaitFor, const BaseType_t xWaitForAllBits ) +{ +BaseType_t xWaitConditionMet = pdFALSE; + + if( xWaitForAllBits == pdFALSE ) + { + /* Task only has to wait for one bit within uxBitsToWaitFor to be + set. Is one already set? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) != ( EventBits_t ) 0 ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Task has to wait for all the bits in uxBitsToWaitFor to be set. + Are they set already? */ + if( ( uxCurrentEventBits & uxBitsToWaitFor ) == uxBitsToWaitFor ) + { + xWaitConditionMet = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return xWaitConditionMet; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) + { + BaseType_t xReturn; + + traceEVENT_GROUP_SET_BITS_FROM_ISR( xEventGroup, uxBitsToSet ); + xReturn = xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ); /*lint !e9087 Can't avoid cast to void* as a generic callback function not specific to this use case. Callback casts back to original type so safe. */ + + return xReturn; + } + +#endif +/*-----------------------------------------------------------*/ + +#if (configUSE_TRACE_FACILITY == 1) + + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) + { + UBaseType_t xReturn; + EventGroup_t const *pxEventBits = ( EventGroup_t * ) xEventGroup; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + + if( xEventGroup == NULL ) + { + xReturn = 0; + } + else + { + xReturn = pxEventBits->uxEventGroupNumber; + } + + return xReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vEventGroupSetNumber( void * xEventGroup, UBaseType_t uxEventGroupNumber ) + { + ( ( EventGroup_t * ) xEventGroup )->uxEventGroupNumber = uxEventGroupNumber; /*lint !e9087 !e9079 EventGroupHandle_t is a pointer to an EventGroup_t, but EventGroupHandle_t is kept opaque outside of this file for data hiding purposes. */ + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.h new file mode 100644 index 0000000..dc627ea --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/event_groups.h @@ -0,0 +1,758 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef EVENT_GROUPS_H +#define EVENT_GROUPS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include event_groups.h" +#endif + +/* FreeRTOS includes. */ +#include "timers.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * An event group is a collection of bits to which an application can assign a + * meaning. For example, an application may create an event group to convey + * the status of various CAN bus related events in which bit 0 might mean "A CAN + * message has been received and is ready for processing", bit 1 might mean "The + * application has queued a message that is ready for sending onto the CAN + * network", and bit 2 might mean "It is time to send a SYNC message onto the + * CAN network" etc. A task can then test the bit values to see which events + * are active, and optionally enter the Blocked state to wait for a specified + * bit or a group of specified bits to be active. To continue the CAN bus + * example, a CAN controlling task can enter the Blocked state (and therefore + * not consume any processing time) until either bit 0, bit 1 or bit 2 are + * active, at which time the bit that was actually active would inform the task + * which action it had to take (process a received message, send a message, or + * send a SYNC). + * + * The event groups implementation contains intelligence to avoid race + * conditions that would otherwise occur were an application to use a simple + * variable for the same purpose. This is particularly important with respect + * to when a bit within an event group is to be cleared, and when bits have to + * be set and then tested atomically - as is the case where event groups are + * used to create a synchronisation point between multiple tasks (a + * 'rendezvous'). + * + * \defgroup EventGroup + */ + + + +/** + * event_groups.h + * + * Type by which event groups are referenced. For example, a call to + * xEventGroupCreate() returns an EventGroupHandle_t variable that can then + * be used as a parameter to other event group functions. + * + * \defgroup EventGroupHandle_t EventGroupHandle_t + * \ingroup EventGroup + */ +struct EventGroupDef_t; +typedef struct EventGroupDef_t * EventGroupHandle_t; + +/* + * The type that holds event bits always matches TickType_t - therefore the + * number of bits it holds is set by configUSE_16_BIT_TICKS (16 bits if set to 1, + * 32 bits if set to 0. + * + * \defgroup EventBits_t EventBits_t + * \ingroup EventGroup + */ +typedef TickType_t EventBits_t; + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreate( void );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @return If the event group was created then a handle to the event group is + * returned. If there was insufficient FreeRTOS heap available to create the + * event group then NULL is returned. See http://www.freertos.org/a00111.html + * + * Example usage: +
+	// Declare a variable to hold the created event group.
+	EventGroupHandle_t xCreatedEventGroup;
+
+	// Attempt to create the event group.
+	xCreatedEventGroup = xEventGroupCreate();
+
+	// Was the event group created successfully?
+	if( xCreatedEventGroup == NULL )
+	{
+		// The event group was not created because there was insufficient
+		// FreeRTOS heap available.
+	}
+	else
+	{
+		// The event group was created.
+	}
+   
+ * \defgroup xEventGroupCreate xEventGroupCreate + * \ingroup EventGroup + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreate( void ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+ EventGroupHandle_t xEventGroupCreateStatic( EventGroupHandle_t * pxEventGroupBuffer );
+ 
+ * + * Create a new event group. + * + * Internally, within the FreeRTOS implementation, event groups use a [small] + * block of memory, in which the event group's structure is stored. If an event + * groups is created using xEventGropuCreate() then the required memory is + * automatically dynamically allocated inside the xEventGroupCreate() function. + * (see http://www.freertos.org/a00111.html). If an event group is created + * using xEventGropuCreateStatic() then the application writer must instead + * provide the memory that will get used by the event group. + * xEventGroupCreateStatic() therefore allows an event group to be created + * without using any dynamic memory allocation. + * + * Although event groups are not related to ticks, for internal implementation + * reasons the number of bits available for use in an event group is dependent + * on the configUSE_16_BIT_TICKS setting in FreeRTOSConfig.h. If + * configUSE_16_BIT_TICKS is 1 then each event group contains 8 usable bits (bit + * 0 to bit 7). If configUSE_16_BIT_TICKS is set to 0 then each event group has + * 24 usable bits (bit 0 to bit 23). The EventBits_t type is used to store + * event bits within an event group. + * + * @param pxEventGroupBuffer pxEventGroupBuffer must point to a variable of type + * StaticEventGroup_t, which will be then be used to hold the event group's data + * structures, removing the need for the memory to be allocated dynamically. + * + * @return If the event group was created then a handle to the event group is + * returned. If pxEventGroupBuffer was NULL then NULL is returned. + * + * Example usage: +
+	// StaticEventGroup_t is a publicly accessible structure that has the same
+	// size and alignment requirements as the real event group structure.  It is
+	// provided as a mechanism for applications to know the size of the event
+	// group (which is dependent on the architecture and configuration file
+	// settings) without breaking the strict data hiding policy by exposing the
+	// real event group internals.  This StaticEventGroup_t variable is passed
+	// into the xSemaphoreCreateEventGroupStatic() function and is used to store
+	// the event group's data structures
+	StaticEventGroup_t xEventGroupBuffer;
+
+	// Create the event group without dynamically allocating any memory.
+	xEventGroup = xEventGroupCreateStatic( &xEventGroupBuffer );
+   
+ */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) PRIVILEGED_FUNCTION; +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupWaitBits( 	EventGroupHandle_t xEventGroup,
+										const EventBits_t uxBitsToWaitFor,
+										const BaseType_t xClearOnExit,
+										const BaseType_t xWaitForAllBits,
+										const TickType_t xTicksToWait );
+ 
+ * + * [Potentially] block to wait for one or more bits to be set within a + * previously created event group. + * + * This function cannot be called from an interrupt. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and/or bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and/or bit 1 and/or bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xClearOnExit If xClearOnExit is set to pdTRUE then any bits within + * uxBitsToWaitFor that are set within the event group will be cleared before + * xEventGroupWaitBits() returns if the wait condition was met (if the function + * returns for a reason other than a timeout). If xClearOnExit is set to + * pdFALSE then the bits set in the event group are not altered when the call to + * xEventGroupWaitBits() returns. + * + * @param xWaitForAllBits If xWaitForAllBits is set to pdTRUE then + * xEventGroupWaitBits() will return when either all the bits in uxBitsToWaitFor + * are set or the specified block time expires. If xWaitForAllBits is set to + * pdFALSE then xEventGroupWaitBits() will return when any one of the bits set + * in uxBitsToWaitFor is set or the specified block time expires. The block + * time is specified by the xTicksToWait parameter. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for one/all (depending on the xWaitForAllBits value) of the bits specified by + * uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupWaitBits() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupWaitBits() returned because the bits it was waiting for were set + * then the returned value is the event group value before any bits were + * automatically cleared in the case that xClearOnExit parameter was set to + * pdTRUE. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+   const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+		// Wait a maximum of 100ms for either bit 0 or bit 4 to be set within
+		// the event group.  Clear the bits before exiting.
+		uxBits = xEventGroupWaitBits(
+					xEventGroup,	// The event group being tested.
+					BIT_0 | BIT_4,	// The bits within the event group to wait for.
+					pdTRUE,			// BIT_0 and BIT_4 should be cleared before returning.
+					pdFALSE,		// Don't wait for both bits, either bit will do.
+					xTicksToWait );	// Wait a maximum of 100ms for either bit to be set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// xEventGroupWaitBits() returned because both bits were set.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_0 was set.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// xEventGroupWaitBits() returned because just BIT_4 was set.
+		}
+		else
+		{
+			// xEventGroupWaitBits() returned because xTicksToWait ticks passed
+			// without either BIT_0 or BIT_4 becoming set.
+		}
+   }
+   
+ * \defgroup xEventGroupWaitBits xEventGroupWaitBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear );
+ 
+ * + * Clear bits within an event group. This function cannot be called from an + * interrupt. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear + * in the event group. For example, to clear bit 3 only, set uxBitsToClear to + * 0x08. To clear bit 3 and bit 0 set uxBitsToClear to 0x09. + * + * @return The value of the event group before the specified bits were cleared. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Clear bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupClearBits(
+								xEventGroup,	// The event group being updated.
+								BIT_0 | BIT_4 );// The bits being cleared.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 were set before xEventGroupClearBits() was
+			// called.  Both will now be clear (not set).
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 was set before xEventGroupClearBits() was called.  It will
+			// now be clear.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 were set in the first place.
+		}
+   }
+   
+ * \defgroup xEventGroupClearBits xEventGroupClearBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * A version of xEventGroupClearBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed + * while interrupts are disabled, so protects event groups that are accessed + * from tasks by suspending the scheduler rather than disabling interrupts. As + * a result event groups cannot be accessed directly from an interrupt service + * routine. Therefore xEventGroupClearBitsFromISR() sends a message to the + * timer task to have the clear operation performed in the context of the timer + * task. + * + * @param xEventGroup The event group in which the bits are to be cleared. + * + * @param uxBitsToClear A bitwise value that indicates the bit or bits to clear. + * For example, to clear bit 3 only, set uxBitsToClear to 0x08. To clear bit 3 + * and bit 0 set uxBitsToClear to 0x09. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+		// Clear bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupClearBitsFromISR(
+							xEventGroup,	 // The event group being updated.
+							BIT_0 | BIT_4 ); // The bits being set.
+
+		if( xResult == pdPASS )
+		{
+			// The message was posted successfully.
+		}
+  }
+   
+ * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToClear, NULL ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet );
+ 
+ * + * Set bits within an event group. + * This function cannot be called from an interrupt. xEventGroupSetBitsFromISR() + * is a version that can be called from an interrupt. + * + * Setting bits in an event group will automatically unblock tasks that are + * blocked waiting for the bits. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @return The value of the event group at the time the call to + * xEventGroupSetBits() returns. There are two reasons why the returned value + * might have the bits specified by the uxBitsToSet parameter cleared. First, + * if setting a bit results in a task that was waiting for the bit leaving the + * blocked state then it is possible the bit will be cleared automatically + * (see the xClearBitOnExit parameter of xEventGroupWaitBits()). Second, any + * unblocked (or otherwise Ready state) task that has a priority above that of + * the task that called xEventGroupSetBits() will execute and may change the + * event group value before the call to xEventGroupSetBits() returns. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   void aFunction( EventGroupHandle_t xEventGroup )
+   {
+   EventBits_t uxBits;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		uxBits = xEventGroupSetBits(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4 );// The bits being set.
+
+		if( ( uxBits & ( BIT_0 | BIT_4 ) ) == ( BIT_0 | BIT_4 ) )
+		{
+			// Both bit 0 and bit 4 remained set when the function returned.
+		}
+		else if( ( uxBits & BIT_0 ) != 0 )
+		{
+			// Bit 0 remained set when the function returned, but bit 4 was
+			// cleared.  It might be that bit 4 was cleared automatically as a
+			// task that was waiting for bit 4 was removed from the Blocked
+			// state.
+		}
+		else if( ( uxBits & BIT_4 ) != 0 )
+		{
+			// Bit 4 remained set when the function returned, but bit 0 was
+			// cleared.  It might be that bit 0 was cleared automatically as a
+			// task that was waiting for bit 0 was removed from the Blocked
+			// state.
+		}
+		else
+		{
+			// Neither bit 0 nor bit 4 remained set.  It might be that a task
+			// was waiting for both of the bits to be set, and the bits were
+			// cleared as the task left the Blocked state.
+		}
+   }
+   
+ * \defgroup xEventGroupSetBits xEventGroupSetBits + * \ingroup EventGroup + */ +EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken );
+ 
+ * + * A version of xEventGroupSetBits() that can be called from an interrupt. + * + * Setting bits in an event group is not a deterministic operation because there + * are an unknown number of tasks that may be waiting for the bit or bits being + * set. FreeRTOS does not allow nondeterministic operations to be performed in + * interrupts or from critical sections. Therefore xEventGroupSetBitsFromISR() + * sends a message to the timer task to have the set operation performed in the + * context of the timer task - where a scheduler lock is used in place of a + * critical section. + * + * @param xEventGroup The event group in which the bits are to be set. + * + * @param uxBitsToSet A bitwise value that indicates the bit or bits to set. + * For example, to set bit 3 only, set uxBitsToSet to 0x08. To set bit 3 + * and bit 0 set uxBitsToSet to 0x09. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task is higher than the priority of the + * currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE by + * xEventGroupSetBitsFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return If the request to execute the function was posted successfully then + * pdPASS is returned, otherwise pdFALSE is returned. pdFALSE will be returned + * if the timer service queue was full. + * + * Example usage: +
+   #define BIT_0	( 1 << 0 )
+   #define BIT_4	( 1 << 4 )
+
+   // An event group which it is assumed has already been created by a call to
+   // xEventGroupCreate().
+   EventGroupHandle_t xEventGroup;
+
+   void anInterruptHandler( void )
+   {
+   BaseType_t xHigherPriorityTaskWoken, xResult;
+
+		// xHigherPriorityTaskWoken must be initialised to pdFALSE.
+		xHigherPriorityTaskWoken = pdFALSE;
+
+		// Set bit 0 and bit 4 in xEventGroup.
+		xResult = xEventGroupSetBitsFromISR(
+							xEventGroup,	// The event group being updated.
+							BIT_0 | BIT_4   // The bits being set.
+							&xHigherPriorityTaskWoken );
+
+		// Was the message posted successfully?
+		if( xResult == pdPASS )
+		{
+			// If xHigherPriorityTaskWoken is now set to pdTRUE then a context
+			// switch should be requested.  The macro used is port specific and
+			// will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() -
+			// refer to the documentation page for the port being used.
+			portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+		}
+  }
+   
+ * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR + * \ingroup EventGroup + */ +#if( configUSE_TRACE_FACILITY == 1 ) + BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#else + #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) xEventGroup, ( uint32_t ) uxBitsToSet, pxHigherPriorityTaskWoken ) +#endif + +/** + * event_groups.h + *
+	EventBits_t xEventGroupSync(	EventGroupHandle_t xEventGroup,
+									const EventBits_t uxBitsToSet,
+									const EventBits_t uxBitsToWaitFor,
+									TickType_t xTicksToWait );
+ 
+ * + * Atomically set bits within an event group, then wait for a combination of + * bits to be set within the same event group. This functionality is typically + * used to synchronise multiple tasks, where each task has to wait for the other + * tasks to reach a synchronisation point before proceeding. + * + * This function cannot be used from an interrupt. + * + * The function will return before its block time expires if the bits specified + * by the uxBitsToWait parameter are set, or become set within that time. In + * this case all the bits specified by uxBitsToWait will be automatically + * cleared before the function returns. + * + * @param xEventGroup The event group in which the bits are being tested. The + * event group must have previously been created using a call to + * xEventGroupCreate(). + * + * @param uxBitsToSet The bits to set in the event group before determining + * if, and possibly waiting for, all the bits specified by the uxBitsToWait + * parameter are set. + * + * @param uxBitsToWaitFor A bitwise value that indicates the bit or bits to test + * inside the event group. For example, to wait for bit 0 and bit 2 set + * uxBitsToWaitFor to 0x05. To wait for bits 0 and bit 1 and bit 2 set + * uxBitsToWaitFor to 0x07. Etc. + * + * @param xTicksToWait The maximum amount of time (specified in 'ticks') to wait + * for all of the bits specified by uxBitsToWaitFor to become set. + * + * @return The value of the event group at the time either the bits being waited + * for became set, or the block time expired. Test the return value to know + * which bits were set. If xEventGroupSync() returned because its timeout + * expired then not all the bits being waited for will be set. If + * xEventGroupSync() returned because all the bits it was waiting for were + * set then the returned value is the event group value before any bits were + * automatically cleared. + * + * Example usage: +
+ // Bits used by the three tasks.
+ #define TASK_0_BIT		( 1 << 0 )
+ #define TASK_1_BIT		( 1 << 1 )
+ #define TASK_2_BIT		( 1 << 2 )
+
+ #define ALL_SYNC_BITS ( TASK_0_BIT | TASK_1_BIT | TASK_2_BIT )
+
+ // Use an event group to synchronise three tasks.  It is assumed this event
+ // group has already been created elsewhere.
+ EventGroupHandle_t xEventBits;
+
+ void vTask0( void *pvParameters )
+ {
+ EventBits_t uxReturn;
+ TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS;
+
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 0 in the event flag to note this task has reached the
+		// sync point.  The other two tasks will set the other two bits defined
+		// by ALL_SYNC_BITS.  All three tasks have reached the synchronisation
+		// point when all the ALL_SYNC_BITS are set.  Wait a maximum of 100ms
+		// for this to happen.
+		uxReturn = xEventGroupSync( xEventBits, TASK_0_BIT, ALL_SYNC_BITS, xTicksToWait );
+
+		if( ( uxReturn & ALL_SYNC_BITS ) == ALL_SYNC_BITS )
+		{
+			// All three tasks reached the synchronisation point before the call
+			// to xEventGroupSync() timed out.
+		}
+	}
+ }
+
+ void vTask1( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 1 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_1_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	 }
+ }
+
+ void vTask2( void *pvParameters )
+ {
+	 for( ;; )
+	 {
+		// Perform task functionality here.
+
+		// Set bit 2 in the event flag to note this task has reached the
+		// synchronisation point.  The other two tasks will set the other two
+		// bits defined by ALL_SYNC_BITS.  All three tasks have reached the
+		// synchronisation point when all the ALL_SYNC_BITS are set.  Wait
+		// indefinitely for this to happen.
+		xEventGroupSync( xEventBits, TASK_2_BIT, ALL_SYNC_BITS, portMAX_DELAY );
+
+		// xEventGroupSync() was called with an indefinite block time, so
+		// this task will only reach here if the syncrhonisation was made by all
+		// three tasks, so there is no need to test the return value.
+	}
+ }
+
+ 
+ * \defgroup xEventGroupSync xEventGroupSync + * \ingroup EventGroup + */ +EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBits( EventGroupHandle_t xEventGroup );
+ 
+ * + * Returns the current value of the bits in an event group. This function + * cannot be used from an interrupt. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBits() was called. + * + * \defgroup xEventGroupGetBits xEventGroupGetBits + * \ingroup EventGroup + */ +#define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) + +/** + * event_groups.h + *
+	EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup );
+ 
+ * + * A version of xEventGroupGetBits() that can be called from an ISR. + * + * @param xEventGroup The event group being queried. + * + * @return The event group bits at the time xEventGroupGetBitsFromISR() was called. + * + * \defgroup xEventGroupGetBitsFromISR xEventGroupGetBitsFromISR + * \ingroup EventGroup + */ +EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/** + * event_groups.h + *
+	void xEventGroupDelete( EventGroupHandle_t xEventGroup );
+ 
+ * + * Delete an event group that was previously created by a call to + * xEventGroupCreate(). Tasks that are blocked on the event group will be + * unblocked and obtain 0 as the event group's value. + * + * @param xEventGroup The event group being deleted. + */ +void vEventGroupDelete( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; + +/* For internal use only. */ +void vEventGroupSetBitsCallback( void *pvEventGroup, const uint32_t ulBitsToSet ) PRIVILEGED_FUNCTION; +void vEventGroupClearBitsCallback( void *pvEventGroup, const uint32_t ulBitsToClear ) PRIVILEGED_FUNCTION; + + +#if (configUSE_TRACE_FACILITY == 1) + UBaseType_t uxEventGroupGetNumber( void* xEventGroup ) PRIVILEGED_FUNCTION; + void vEventGroupSetNumber( void* xEventGroup, UBaseType_t uxEventGroupNumber ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* EVENT_GROUPS_H */ + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/freertos_tasks_c_additions.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/freertos_tasks_c_additions.h new file mode 100644 index 0000000..8b09ef2 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/freertos_tasks_c_additions.h @@ -0,0 +1,138 @@ +/* + * Copyright 2017-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* freertos_tasks_c_additions.h Rev. 1.4 */ +#ifndef FREERTOS_TASKS_C_ADDITIONS_H +#define FREERTOS_TASKS_C_ADDITIONS_H + +#include +#if !defined(__HIWARE__) /* << EST */ + #include +#endif + +#if (configUSE_TRACE_FACILITY == 0) +#error "configUSE_TRACE_FACILITY must be enabled" +#endif + +#define FREERTOS_DEBUG_CONFIG_MAJOR_VERSION 1 +#define FREERTOS_DEBUG_CONFIG_MINOR_VERSION 2 + +/* NOTE!! + * Default to a FreeRTOS version which didn't include these macros. FreeRTOS + * v7.5.3 is used here. + */ +#ifndef tskKERNEL_VERSION_BUILD +#define tskKERNEL_VERSION_BUILD 3 +#endif +#ifndef tskKERNEL_VERSION_MINOR +#define tskKERNEL_VERSION_MINOR 5 +#endif +#ifndef tskKERNEL_VERSION_MAJOR +#define tskKERNEL_VERSION_MAJOR 7 +#endif + +/* NOTE!! + * The configFRTOS_MEMORY_SCHEME macro describes the heap scheme using a value + * 1 - 5 which corresponds to the following schemes: + * + * heap_1 - the very simplest, does not permit memory to be freed + * heap_2 - permits memory to be freed, but not does coalescence adjacent free + * blocks. + * heap_3 - simply wraps the standard malloc() and free() for thread safety + * heap_4 - coalesces adjacent free blocks to avoid fragmentation. Includes + * absolute address placement option + * heap_5 - as per heap_4, with the ability to span the heap across + * multiple nonOadjacent memory areas + * heap_6 - reentrant newlib implementation + */ +#ifndef configUSE_HEAP_SCHEME + #define configUSE_HEAP_SCHEME 3 /* thread safe malloc */ +#endif + +#if ((configUSE_HEAP_SCHEME > 6) || (configUSE_HEAP_SCHEME < 1)) /* <= 10) && (tskKERNEL_VERSION_MINOR >= 2) +// Need the portARCH_NAME define +#ifndef portARCH_NAME +#define portARCH_NAME NULL +#endif +#if defined(__GNUC__) +char *const portArch_Name __attribute__((section(".rodata"))) = portARCH_NAME; +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) +char *const portArch_Name __attribute__((used)) = portARCH_NAME; +#elif defined(__IAR_SYSTEMS_ICC__) +#pragma required=portArch_Name +char *const portArch_Name = portARCH_NAME; +#endif +#else +char *const portArch_Name = NULL; +#endif // tskKERNEL_VERSION_MAJOR + +#if defined(__GNUC__) + const uint8_t FreeRTOSDebugConfig[] __attribute__((section(".rodata"))) = +#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) + const uint8_t FreeRTOSDebugConfig[] __attribute__((used)) = +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma required=FreeRTOSDebugConfig + const uint8_t FreeRTOSDebugConfig[] = +#else /* << EST generic compiler */ + const uint8_t FreeRTOSDebugConfig[] = +#endif +{ + FREERTOS_DEBUG_CONFIG_MAJOR_VERSION, + FREERTOS_DEBUG_CONFIG_MINOR_VERSION, + tskKERNEL_VERSION_MAJOR, + tskKERNEL_VERSION_MINOR, + tskKERNEL_VERSION_BUILD, + configUSE_HEAP_SCHEME, + offsetof(struct tskTaskControlBlock, pxTopOfStack), +#if (tskKERNEL_VERSION_MAJOR > 8) + offsetof(struct tskTaskControlBlock, xStateListItem), +#else + offsetof(struct tskTaskControlBlock, xGenericListItem), +#endif + offsetof(struct tskTaskControlBlock, xEventListItem), + offsetof(struct tskTaskControlBlock, pxStack), + offsetof(struct tskTaskControlBlock, pcTaskName), + offsetof(struct tskTaskControlBlock, uxTCBNumber), + offsetof(struct tskTaskControlBlock, uxTaskNumber), + configMAX_TASK_NAME_LEN, + configMAX_PRIORITIES, +#if (tskKERNEL_VERSION_MAJOR >= 10) && (tskKERNEL_VERSION_MINOR >= 2) + configENABLE_MPU, + configENABLE_FPU, + configENABLE_TRUSTZONE, + configRUN_FREERTOS_SECURE_ONLY, + 0, // 32-bit align + 0, 0, 0, 0 // padding +#else + 0 // pad to 32-bit boundary +#endif +}; + +#ifdef __cplusplus +} +#endif + +#endif // FREERTOS_TASKS_C_ADDITIONS_H + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_1.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_1.c new file mode 100644 index 0000000..f540c1d --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_1.c @@ -0,0 +1,168 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==1 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * The simplest possible implementation of pvPortMalloc(). Note that this + * implementation does NOT allow allocated memory to be freed again. + * + * See heap_2.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[configTOTAL_HEAP_SIZE]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Index into the ucHeap array. */ +static size_t xNextFreeByte = ( size_t ) 0; + +/*-----------------------------------------------------------*/ +static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn = NULL; +//static uint8_t *pucAlignedHeap = NULL; /* << EST: make it global os it can be re-initialized */ + + /* Ensure that blocks are always aligned to the required number of bytes. */ + #if( portBYTE_ALIGNMENT != 1 ) + { + if( xWantedSize & portBYTE_ALIGNMENT_MASK ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + #endif + + vTaskSuspendAll(); + { + if( pucAlignedHeap == NULL ) + { + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + } + + /* Check there is enough room left for the allocation. */ + if( ( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) && + ( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) )/* Check for overflow. */ + { + /* Return the next free byte then increment the index past this + block. */ + pvReturn = pucAlignedHeap + xNextFreeByte; + xNextFreeByte += xWantedSize; + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + /* Memory cannot be freed using this scheme. See heap_2.c, heap_3.c and + heap_4.c for alternative implementations, and the memory management pages of + http://www.FreeRTOS.org for more information. */ + ( void ) pv; + + /* Force an assert as it is invalid to call this function. */ + configASSERT( pv == NULL ); +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* Only required when static memory is not cleared. */ + xNextFreeByte = ( size_t ) 0; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return ( configADJUSTED_HEAP_SIZE - xNextFreeByte ); +} + +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xNextFreeByte = 0; + pucAlignedHeap = NULL; +} +#endif + +#endif /* configUSE_HEAP_SCHEME==1 */ /* << EST */ + + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_2.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_2.c new file mode 100644 index 0000000..97febb0 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_2.c @@ -0,0 +1,296 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==2 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that permits + * allocated blocks to be freed, but does not combine adjacent free blocks + * into a single larger block (and so will fragment memory). See heap_4.c for + * an equivalent that does combine adjacent blocks into single larger blocks. + * + * See heap_1.c, heap_3.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* A few bytes might be lost to byte aligning the heap start address. */ +#define configADJUSTED_HEAP_SIZE ( configTOTAL_HEAP_SIZE - portBYTE_ALIGNMENT ) + +/* + * Initialises the heap structures before their first use. + */ +static void prvHeapInit( void ); + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static uint8_t ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static uint8_t __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + + +/* Define the linked list structure. This is used to link free blocks in order +of their size. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + + +static const uint16_t heapSTRUCT_SIZE = ( ( sizeof ( BlockLink_t ) + ( portBYTE_ALIGNMENT - 1 ) ) & ~portBYTE_ALIGNMENT_MASK ); +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( heapSTRUCT_SIZE * 2 ) ) + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, xEnd; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + +/* STATIC FUNCTIONS ARE DEFINED AS MACROS TO MINIMIZE THE FUNCTION CALL DEPTH. */ + +/* + * Insert a block into the list of free blocks - which is ordered by size of + * the block. Small blocks at the start of the list and large blocks at the end + * of the list. + */ +#define prvInsertBlockIntoFreeList( pxBlockToInsert ) \ +{ \ +BlockLink_t *pxIterator; \ +size_t xBlockSize; \ + \ + xBlockSize = pxBlockToInsert->xBlockSize; \ + \ + /* Iterate through the list until a block is found that has a larger size */ \ + /* than the block we are inserting. */ \ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock->xBlockSize < xBlockSize; pxIterator = pxIterator->pxNextFreeBlock ) \ + { \ + /* There is nothing to do here - just iterate to the correct position. */ \ + } \ + \ + /* Update the list to include the block being inserted in the correct */ \ + /* position. */ \ + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; \ + pxIterator->pxNextFreeBlock = pxBlockToInsert; \ +} +/*-----------------------------------------------------------*/ +static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +//static BaseType_t xHeapHasBeenInitialised = pdFALSE; /* << EST: make it global os it can be re-initialized */ +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( xHeapHasBeenInitialised == pdFALSE ) + { + prvHeapInit(); + xHeapHasBeenInitialised = pdTRUE; + } + + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += heapSTRUCT_SIZE; + + /* Ensure that blocks are always aligned to the required number of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + } + + if( ( xWantedSize > 0 ) && ( xWantedSize < configADJUSTED_HEAP_SIZE ) ) + { + /* Blocks are stored in byte order - traverse the list from the start + (smallest) block until one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If we found the end marker then a block of adequate size was not found. */ + if( pxBlock != &xEnd ) + { + /* Return the memory space - jumping over the BlockLink_t structure + at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + heapSTRUCT_SIZE ); + + /* This block is being returned for use so must be taken out of the + list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new block + following the number of bytes requested. The void cast is + used to prevent byte alignment warnings from the compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the single + block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + } + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= heapSTRUCT_SIZE; + + /* This unexpected casting is to keep some compilers from issuing + byte alignment warnings. */ + pxLink = ( void * ) puc; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; + + /* Ensure the heap starts on a correctly aligned boundary. */ + pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) &ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* xEnd is used to mark the end of the list of free blocks. */ + xEnd.xBlockSize = configADJUSTED_HEAP_SIZE; + xEnd.pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = configADJUSTED_HEAP_SIZE; + pxFirstFreeBlock->pxNextFreeBlock = &xEnd; +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xEnd.pxNextFreeBlock = NULL; + xEnd.xBlockSize = 0; + xFreeBytesRemaining = configADJUSTED_HEAP_SIZE; + xHeapHasBeenInitialised = pdFALSE; +} +#endif +#endif /* configUSE_HEAP_SCHEME==2 */ /* << EST */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_3.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_3.c new file mode 100644 index 0000000..5d6a383 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_3.c @@ -0,0 +1,109 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==3 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.0 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Implementation of pvPortMalloc() and vPortFree() that relies on the + * compilers own malloc() and free() implementations. + * + * This file can only be used if the linker is configured to to generate + * a heap memory area. + * + * See heap_1.c, heap_2.c and heap_4.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ + +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +void *pvReturn; + + vTaskSuspendAll(); + { + pvReturn = malloc( xWantedSize ); + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ + if( pv ) + { + vTaskSuspendAll(); + { + free( pv ); + traceFREE( pv, 0 ); + } + ( void ) xTaskResumeAll(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* configUSE_HEAP_SCHEME==3 */ /* << EST */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_4.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_4.c new file mode 100644 index 0000000..3596d8f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_4.c @@ -0,0 +1,467 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==4 && configSUPPORT_DYNAMIC_ALLOCATION==1) + +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of http://www.FreeRTOS.org for more information. + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Allocate the memory for the heap. */ +#if( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#elif configUSE_HEAP_SECTION_NAME && configCOMPILER==configCOMPILER_ARM_IAR /* << EST */ + #pragma language=extended + #pragma location = configHEAP_SECTION_NAME_STRING + static unsigned char ucHeap[configTOTAL_HEAP_SIZE] @ configHEAP_SECTION_NAME_STRING; +#elif configUSE_HEAP_SECTION_NAME + static unsigned char __attribute__((section (configHEAP_SECTION_NAME_STRING))) ucHeap[configTOTAL_HEAP_SIZE]; +#elif( configAPPLICATION_ALLOCATED_HEAP == 1 ) + /* The application writer has already defined the array used for the RTOS + heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#else + static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +#if 0 +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#else /* << EST do not optimize this variable, needed for NXP TAD plugin */ +static const volatile size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); +#endif + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) +{ +BlockLink_t *pxFirstFreeBlock; +uint8_t *pucAlignedHeap; +size_t uxAddress; +size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( portBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + pxEnd = NULL; /* force initialization of heap next time a block gets allocated */ + xStart.pxNextFreeBlock = NULL; + xStart.xBlockSize = 0; + xFreeBytesRemaining = 0; + xMinimumEverFreeBytesRemaining = 0; + xBlockAllocatedBit = 0; +} +#endif +#endif /* configUSE_HEAP_SCHEME==4 */ /* << EST */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_5.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_5.c new file mode 100644 index 0000000..475f185 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_5.c @@ -0,0 +1,499 @@ +/* << EST */ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==5 && configSUPPORT_DYNAMIC_ALLOCATION==1) +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * A sample implementation of pvPortMalloc() that allows the heap to be defined + * across multiple non-contigous blocks and combines (coalescences) adjacent + * memory blocks as they are freed. + * + * See heap_1.c, heap_2.c, heap_3.c and heap_4.c for alternative + * implementations, and the memory management pages of http://www.FreeRTOS.org + * for more information. + * + * Usage notes: + * + * vPortDefineHeapRegions() ***must*** be called before pvPortMalloc(). + * pvPortMalloc() will be called if any task objects (tasks, queues, event + * groups, etc.) are created, therefore vPortDefineHeapRegions() ***must*** be + * called before any other objects are defined. + * + * vPortDefineHeapRegions() takes a single parameter. The parameter is an array + * of HeapRegion_t structures. HeapRegion_t is defined in portable.h as + * + * typedef struct HeapRegion + * { + * uint8_t *pucStartAddress; << Start address of a block of memory that will be part of the heap. + * size_t xSizeInBytes; << Size of the block of memory. + * } HeapRegion_t; + * + * The array is terminated using a NULL zero sized region definition, and the + * memory regions defined in the array ***must*** appear in address order from + * low address to high address. So the following is a valid example of how + * to use the function. + * + * HeapRegion_t xHeapRegions[] = + * { + * { ( uint8_t * ) 0x80000000UL, 0x10000 }, << Defines a block of 0x10000 bytes starting at address 0x80000000 + * { ( uint8_t * ) 0x90000000UL, 0xa0000 }, << Defines a block of 0xa0000 bytes starting at address of 0x90000000 + * { NULL, 0 } << Terminates the array. + * }; + * + * vPortDefineHeapRegions( xHeapRegions ); << Pass the array into vPortDefineHeapRegions(). + * + * Note 0x80000000 is the lower address so appears in the array first. + * + */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Define the linked list structure. This is used to link free blocks in order +of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK *pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ); + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory +block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +static BlockLink_t xStart, *pxEnd = NULL; + +/* Keeps track of the number of free bytes remaining, but says nothing about +fragmentation. */ +static size_t xFreeBytesRemaining = 0U; +static size_t xMinimumEverFreeBytesRemaining = 0U; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize +member of an BlockLink_t structure is set then the block belongs to the +application. When the bit is free the block is still part of the free heap +space. */ +static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void *pvPortMalloc( size_t xWantedSize ) +{ +BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; +void *pvReturn = NULL; + + /* The heap must be initialised before the first call to + prvPortMalloc(). */ + configASSERT( pxEnd ); + + vTaskSuspendAll(); + { + /* Check the requested block size is not so large that the top bit is + set. The top bit of the block size member of the BlockLink_t structure + is used to determine who owns the block - the application or the + kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size is increased so it can contain a BlockLink_t + structure in addition to the requested amount of bytes. */ + if( xWantedSize > 0 ) + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned to the required number + of bytes. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. */ + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + block following the number of bytes requested. The void + cast is used to prevent byte alignment warnings from the + compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + + /* Calculate the sizes of two blocks split from the + single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( ( pxNewBlockLink ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceMALLOC( pvReturn, xWantedSize ); + } + ( void ) xTaskResumeAll(); + + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + /* EST: Using configuration macro name for hook */ + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void *pv ) +{ +uint8_t *puc = ( uint8_t * ) pv; +BlockLink_t *pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t *pxBlockToInsert ) +{ +BlockLink_t *pxIterator; +uint8_t *puc; + + /* Iterate through the list until a block is found that has a higher address + than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + before and the block after, then it's pxNextFreeBlock pointer will have + already been set, and should not be set here as that would make it point + to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) +{ +BlockLink_t *pxFirstFreeBlockInRegion = NULL, *pxPreviousFreeBlock; +size_t xAlignedHeap; +size_t xTotalRegionSize, xTotalHeapSize = 0; +BaseType_t xDefinedRegions = 0; +size_t xAddress; +const HeapRegion_t *pxHeapRegion; + + /* Can only call once! */ + configASSERT( pxEnd == NULL ); + + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + + while( pxHeapRegion->xSizeInBytes > 0 ) + { + xTotalRegionSize = pxHeapRegion->xSizeInBytes; + + /* Ensure the heap region starts on a correctly aligned boundary. */ + xAddress = ( size_t ) pxHeapRegion->pucStartAddress; + if( ( xAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + xAddress += ( portBYTE_ALIGNMENT - 1 ); + xAddress &= ~portBYTE_ALIGNMENT_MASK; + + /* Adjust the size for the bytes lost to alignment. */ + xTotalRegionSize -= xAddress - ( size_t ) pxHeapRegion->pucStartAddress; + } + + xAlignedHeap = xAddress; + + /* Set xStart if it has not already been set. */ + if( xDefinedRegions == 0 ) + { + /* xStart is used to hold a pointer to the first item in the list of + free blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( BlockLink_t * ) xAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + } + else + { + /* Should only get here if one region has already been added to the + heap. */ + configASSERT( pxEnd != NULL ); + + /* Check blocks are passed in with increasing start addresses. */ + configASSERT( xAddress > ( size_t ) pxEnd ); + } + + /* Remember the location of the end marker in the previous region, if + any. */ + pxPreviousFreeBlock = pxEnd; + + /* pxEnd is used to mark the end of the list of free blocks and is + inserted at the end of the region space. */ + xAddress = xAlignedHeap + xTotalRegionSize; + xAddress -= xHeapStructSize; + xAddress &= ~portBYTE_ALIGNMENT_MASK; + pxEnd = ( BlockLink_t * ) xAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block in this region that is + sized to take up the entire heap region minus the space taken by the + free block structure. */ + pxFirstFreeBlockInRegion = ( BlockLink_t * ) xAlignedHeap; + pxFirstFreeBlockInRegion->xBlockSize = xAddress - ( size_t ) pxFirstFreeBlockInRegion; + pxFirstFreeBlockInRegion->pxNextFreeBlock = pxEnd; + + /* If this is not the first region that makes up the entire heap space + then link the previous region to this region. */ + if( pxPreviousFreeBlock != NULL ) + { + pxPreviousFreeBlock->pxNextFreeBlock = pxFirstFreeBlockInRegion; + } + + xTotalHeapSize += pxFirstFreeBlockInRegion->xBlockSize; + + /* Move onto the next HeapRegion_t structure. */ + xDefinedRegions++; + pxHeapRegion = &( pxHeapRegions[ xDefinedRegions ] ); + } + + xMinimumEverFreeBytesRemaining = xTotalHeapSize; + xFreeBytesRemaining = xTotalHeapSize; + + /* Check something was actually defined before it is accessed. */ + configASSERT( xTotalHeapSize ); + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +/*-----------------------------------------------------------*/ + +#endif /* configUSE_HEAP_SCHEME==5 */ /* << EST */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.c new file mode 100644 index 0000000..c161cf5 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.c @@ -0,0 +1,200 @@ +#include "FreeRTOSConfig.h" +#if !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) +/** + * \file heap_useNewlib.c + * \brief Wrappers required to use newlib malloc-family within FreeRTOS. + * + * \par Overview + * Route FreeRTOS memory management functions to newlib's malloc family. + * Thus newlib and FreeRTOS share memory-management routines and memory pool, + * and all newlib's internal memory-management requirements are supported. + * + * \author Dave Nadler + * \date 1-July-2017 + * + * \see https://sourceware.org/newlib/libc.html#Reentrancy + * \see https://sourceware.org/newlib/libc.html#malloc + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fenv_005flock + * \see https://sourceware.org/newlib/libc.html#index-_005f_005fmalloc_005flock + * \see https://sourceforge.net/p/freertos/feature-requests/72/ + * \see http://www.billgatliff.com/newlib.html + * \see http://wiki.osdev.org/Porting_Newlib + * \see http://www.embecosm.com/appnotes/ean9/ean9-howto-newlib-1.0.html + * + * + * \copyright + * (c) Dave Nadler 2017, All Rights Reserved. + * Web: http://www.nadler.com + * email: drn@nadler.com + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Use or redistributions of source code must retain the above copyright notice, + * this list of conditions, ALL ORIGINAL COMMENTS, and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include // maps to newlib... +#include // mallinfo... +#include // ENOMEM + +#include "freeRTOS.h" // defines public interface we're implementing here +#if !defined(configUSE_NEWLIB_REENTRANT) || (configUSE_NEWLIB_REENTRANT!=1) + #warning "#define configUSE_NEWLIB_REENTRANT 1 // Required for thread-safety of newlib sprintf, strtok, etc..." + // If you're *really* sure you don't need FreeRTOS's newlib reentrancy support, remove this warning... +#endif +#include "task.h" + +// ================================================================================================ +// External routines required by newlib's malloc (sbrk/_sbrk, __malloc_lock/unlock) +// ================================================================================================ + +#if 0 // suggested minimal implementation from https://sourceware.org/newlib/libc.html#Syscalls: + // sbrk: Increase program data space. As malloc and related functions depend on this, + // it is useful to have a working implementation. The following suffices for a standalone system; + // it exploits the symbol _end automatically defined by the GNU linker. + caddr_t sbrk(int incr) { + extern char _end; /* Defined by the linker */ + static char *heap_end; + char *prev_heap_end; + if (heap_end == 0) { + heap_end = &_end; + } + prev_heap_end = heap_end; + if (heap_end + incr > stack_ptr) { + write (1, "Heap and stack collision\n", 25); + abort (); + } + heap_end += incr; + return (caddr_t) prev_heap_end; + } +#endif +#if 0 // Freescale implementation + caddr_t _sbrk(int incr) + { + extern char end __asm("end"); + extern char heap_limit __asm("__HeapLimit"); + static char *heap_end; + char *prev_heap_end; + if (heap_end == NULL) + heap_end = &end; + prev_heap_end = heap_end; + if (heap_end + incr > &heap_limit) + { + errno = ENOMEM; + return (caddr_t)-1; + } + heap_end += incr; + return (caddr_t)prev_heap_end; + } +#endif + +#ifndef NDEBUG + static int totalBytesProvidedBySBRK = 0; +#endif +extern char configLINKER_HEAP_BASE_SYMBOL, configLINKER_HEAP_LIMIT_SYMBOL, configLINKER_HEAP_SIZE_SYMBOL; // make sure to define these symbols in linker command file +static int heapBytesRemaining = (int)&configLINKER_HEAP_SIZE_SYMBOL; // that's (&__HeapLimit)-(&__HeapBase) + +//! sbrk/_sbrk version supporting reentrant newlib (depends upon above symbols defined by linker control file). +char * sbrk(int incr) { + static char *currentHeapEnd = &configLINKER_HEAP_BASE_SYMBOL; + vTaskSuspendAll(); // Note: safe to use before FreeRTOS scheduler started + char *previousHeapEnd = currentHeapEnd; + if (currentHeapEnd + incr > &configLINKER_HEAP_LIMIT_SYMBOL) { + #if( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + extern void configUSE_MALLOC_FAILED_HOOK_NAME( void ); + configUSE_MALLOC_FAILED_HOOK_NAME(); + } + #elif 0 + // If you want to alert debugger or halt... + while(1) { __asm("bkpt #0"); }; // Stop in GUI as if at a breakpoint (if debugging, otherwise loop forever) + #else + // If you prefer to believe your application will gracefully trap out-of-memory... + _impure_ptr->_errno = ENOMEM; // newlib's thread-specific errno + xTaskResumeAll(); + #endif + return (char *)-1; // the malloc-family routine that called sbrk will return 0 + } + currentHeapEnd += incr; + heapBytesRemaining -= incr; + #ifndef NDEBUG + totalBytesProvidedBySBRK += incr; + #endif + xTaskResumeAll(); + return (char *) previousHeapEnd; +} +//! Synonym for sbrk. +char * _sbrk(int incr) { return sbrk(incr); }; + +void __malloc_lock(struct _reent *p) { vTaskSuspendAll(); }; +void __malloc_unlock(struct _reent *p) { (void)xTaskResumeAll(); }; + +// newlib also requires implementing locks for the application's environment memory space, +// accessed by newlib's setenv() and getenv() functions. +// As these are trivial functions, momentarily suspend task switching (rather than semaphore). +// ToDo: Move __env_lock/unlock to a separate newlib helper file. +void __env_lock() { vTaskSuspendAll(); }; +void __env_unlock() { (void)xTaskResumeAll(); }; + +/// /brief Wrap malloc/malloc_r to help debug who requests memory and why. +/// Add to the linker command line: -Xlinker --wrap=malloc -Xlinker --wrap=_malloc_r +// Note: These functions are normally unused and stripped by linker. +void *__wrap_malloc(size_t nbytes) { + extern void * __real_malloc(size_t nbytes); + void *p = __real_malloc(nbytes); // Solely for debug breakpoint... + return p; +}; +void *__wrap__malloc_r(void *reent, size_t nbytes) { + extern void * __real__malloc_r(size_t nbytes); + void *p = __real__malloc_r(nbytes); // Solely for debug breakpoint... + return p; +}; + + +// ================================================================================================ +// Implement FreeRTOS's memory API using newlib-provided malloc family. +// ================================================================================================ + +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION { + void *p = malloc(xSize); + return p; +} +void vPortFree( void *pv ) PRIVILEGED_FUNCTION { + free(pv); +}; + +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION { + struct mallinfo mi = mallinfo(); + return mi.fordblks + heapBytesRemaining; +} + +// GetMinimumEverFree is not available in newlib's malloc implementation. +// So, no implementation provided: size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; + +//! No implementation needed, but stub provided in case application already calls vPortInitialiseBlocks +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION {}; + +/*-----------------------------------------------------------*/ +#if 1 /* << EST */ +void vPortInitializeHeap(void) { + /* sorry, not able to free up the standard library heap */ +} +#endif + +#endif /* !defined(configUSE_HEAP_SCHEME) || (configUSE_HEAP_SCHEME==6) */ diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.txt b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.txt new file mode 100644 index 0000000..e0ddeb9 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/heap_useNewlib.txt @@ -0,0 +1,7 @@ +heap_useNewlib.txt +------------------ + +For details, see +- http://www.nadler.com/embedded/newlibAndFreeRTOS.html +- http://mcuoneclipse.com/2017/07/02/using-freertos-with-newlib-and-newlib-nano + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.c new file mode 100644 index 0000000..d304411 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.c @@ -0,0 +1,199 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#include +#include "FreeRTOS.h" +#include "list.h" + +/*----------------------------------------------------------- + * PUBLIC LIST API documented in list.h + *----------------------------------------------------------*/ + +void vListInitialise( List_t * const pxList ) +{ + /* The list structure contains a list item which is used to mark the + end of the list. To initialise the list the list end is inserted + as the only list entry. */ + pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + /* The list end value is the highest possible value in the list to + ensure it remains at the end of the list. */ + pxList->xListEnd.xItemValue = portMAX_DELAY; + + /* The list end next and previous pointers point to itself so we know + when the list is empty. */ + pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd );/*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ + + pxList->uxNumberOfItems = ( UBaseType_t ) 0U; + + /* Write known values into the list if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ); + listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ); +} +/*-----------------------------------------------------------*/ + +void vListInitialiseItem( ListItem_t * const pxItem ) +{ + /* Make sure the list item is not recorded as being on a list. */ + pxItem->pxContainer = NULL; + + /* Write known values into the list item if + configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); + listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ); +} +/*-----------------------------------------------------------*/ + +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t * const pxIndex = pxList->pxIndex; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert a new list item into pxList, but rather than sort the list, + makes the new list item the last item to be removed by a call to + listGET_OWNER_OF_NEXT_ENTRY(). */ + pxNewListItem->pxNext = pxIndex; + pxNewListItem->pxPrevious = pxIndex->pxPrevious; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + pxIndex->pxPrevious->pxNext = pxNewListItem; + pxIndex->pxPrevious = pxNewListItem; + + /* Remember which list the item is in. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) +{ +ListItem_t *pxIterator; +const TickType_t xValueOfInsertion = pxNewListItem->xItemValue; + + /* Only effective when configASSERT() is also defined, these tests may catch + the list data structures being overwritten in memory. They will not catch + data errors caused by incorrect configuration or use of FreeRTOS. */ + listTEST_LIST_INTEGRITY( pxList ); + listTEST_LIST_ITEM_INTEGRITY( pxNewListItem ); + + /* Insert the new list item into the list, sorted in xItemValue order. + + If the list already contains a list item with the same item value then the + new list item should be placed after it. This ensures that TCBs which are + stored in ready lists (all of which have the same xItemValue value) get a + share of the CPU. However, if the xItemValue is the same as the back marker + the iteration loop below will not end. Therefore the value is checked + first, and the algorithm slightly modified if necessary. */ + if( xValueOfInsertion == portMAX_DELAY ) + { + pxIterator = pxList->xListEnd.pxPrevious; + } + else + { + /* *** NOTE *********************************************************** + If you find your application is crashing here then likely causes are + listed below. In addition see https://www.freertos.org/FAQHelp.html for + more tips, and ensure configASSERT() is defined! + https://www.freertos.org/a00110.html#configASSERT + + 1) Stack overflow - + see https://www.freertos.org/Stacks-and-stack-overflow-checking.html + 2) Incorrect interrupt priority assignment, especially on Cortex-M + parts where numerically high priority values denote low actual + interrupt priorities, which can seem counter intuitive. See + https://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition + of configMAX_SYSCALL_INTERRUPT_PRIORITY on + https://www.freertos.org/a00110.html + 3) Calling an API function from within a critical section or when + the scheduler is suspended, or calling an API function that does + not end in "FromISR" from an interrupt. + 4) Using a queue or semaphore before it has been initialised or + before the scheduler has been started (are interrupts firing + before vTaskStartScheduler() has been called?). + **********************************************************************/ + + for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. *//*lint !e440 The iterator moves to a different value, not xValueOfInsertion. */ + { + /* There is nothing to do here, just iterating to the wanted + insertion position. */ + } + } + + pxNewListItem->pxNext = pxIterator->pxNext; + pxNewListItem->pxNext->pxPrevious = pxNewListItem; + pxNewListItem->pxPrevious = pxIterator; + pxIterator->pxNext = pxNewListItem; + + /* Remember which list the item is in. This allows fast removal of the + item later. */ + pxNewListItem->pxContainer = pxList; + + ( pxList->uxNumberOfItems )++; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) +{ +/* The list item knows which list it is in. Obtain the list from the list +item. */ +List_t * const pxList = pxItemToRemove->pxContainer; + + pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious; + pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext; + + /* Only used during decision coverage testing. */ + mtCOVERAGE_TEST_DELAY(); + + /* Make sure the index is left pointing to a valid item. */ + if( pxList->pxIndex == pxItemToRemove ) + { + pxList->pxIndex = pxItemToRemove->pxPrevious; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxItemToRemove->pxContainer = NULL; + ( pxList->uxNumberOfItems )--; + + return pxList->uxNumberOfItems; +} +/*-----------------------------------------------------------*/ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.h new file mode 100644 index 0000000..355ff81 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/list.h @@ -0,0 +1,413 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * This is the list implementation used by the scheduler. While it is tailored + * heavily for the schedulers needs, it is also available for use by + * application code. + * + * list_ts can only store pointers to list_item_ts. Each ListItem_t contains a + * numeric value (xItemValue). Most of the time the lists are sorted in + * descending item value order. + * + * Lists are created already containing one list item. The value of this + * item is the maximum possible that can be stored, it is therefore always at + * the end of the list and acts as a marker. The list member pxHead always + * points to this marker - even though it is at the tail of the list. This + * is because the tail contains a wrap back pointer to the true head of + * the list. + * + * In addition to it's value, each list item contains a pointer to the next + * item in the list (pxNext), a pointer to the list it is in (pxContainer) + * and a pointer to back to the object that contains it. These later two + * pointers are included for efficiency of list manipulation. There is + * effectively a two way link between the object containing the list item and + * the list item itself. + * + * + * \page ListIntroduction List Implementation + * \ingroup FreeRTOSIntro + */ + +#ifndef INC_FREERTOS_H + #error FreeRTOS.h must be included before list.h +#endif + +#ifndef LIST_H +#define LIST_H + +/* + * The list structure members are modified from within interrupts, and therefore + * by rights should be declared volatile. However, they are only modified in a + * functionally atomic way (within critical sections of with the scheduler + * suspended) and are either passed by reference into a function or indexed via + * a volatile variable. Therefore, in all use cases tested so far, the volatile + * qualifier can be omitted in order to provide a moderate performance + * improvement without adversely affecting functional behaviour. The assembly + * instructions generated by the IAR, ARM and GCC compilers when the respective + * compiler's options were set for maximum optimisation has been inspected and + * deemed to be as intended. That said, as compiler technology advances, and + * especially if aggressive cross module optimisation is used (a use case that + * has not been exercised to any great extend) then it is feasible that the + * volatile qualifier will be needed for correct optimisation. It is expected + * that a compiler removing essential code because, without the volatile + * qualifier on the list structure members and with aggressive cross module + * optimisation, the compiler deemed the code unnecessary will result in + * complete and obvious failure of the scheduler. If this is ever experienced + * then the volatile qualifier can be inserted in the relevant places within the + * list structures by simply defining configLIST_VOLATILE to volatile in + * FreeRTOSConfig.h (as per the example at the bottom of this comment block). + * If configLIST_VOLATILE is not defined then the preprocessor directives below + * will simply #define configLIST_VOLATILE away completely. + * + * To use volatile list structure members then add the following line to + * FreeRTOSConfig.h (without the quotes): + * "#define configLIST_VOLATILE volatile" + */ +#ifndef configLIST_VOLATILE + #define configLIST_VOLATILE +#endif /* configSUPPORT_CROSS_MODULE_OPTIMISATION */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Macros that can be used to place known values within the list structures, +then check that the known values do not get corrupted during the execution of +the application. These may catch the list data structures being overwritten in +memory. They will not catch data errors caused by incorrect configuration or +use of FreeRTOS.*/ +#if( configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES == 0 ) + /* Define the macros to do nothing. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) + #define listTEST_LIST_INTEGRITY( pxList ) +#else + /* Define macros that add new members into the list structures. */ + #define listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue1; + #define listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE TickType_t xListItemIntegrityValue2; + #define listFIRST_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue1; + #define listSECOND_LIST_INTEGRITY_CHECK_VALUE TickType_t xListIntegrityValue2; + + /* Define macros that set the new structure members to known values. */ + #define listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem ) ( pxItem )->xListItemIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList ) ( pxList )->xListIntegrityValue1 = pdINTEGRITY_CHECK_VALUE + #define listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList ) ( pxList )->xListIntegrityValue2 = pdINTEGRITY_CHECK_VALUE + + /* Define macros that will assert if one of the structure members does not + contain its expected value. */ + #define listTEST_LIST_ITEM_INTEGRITY( pxItem ) configASSERT( ( ( pxItem )->xListItemIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxItem )->xListItemIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) + #define listTEST_LIST_INTEGRITY( pxList ) configASSERT( ( ( pxList )->xListIntegrityValue1 == pdINTEGRITY_CHECK_VALUE ) && ( ( pxList )->xListIntegrityValue2 == pdINTEGRITY_CHECK_VALUE ) ) +#endif /* configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES */ + + +/* + * Definition of the only type of object that a list can contain. + */ +struct xLIST; +struct xLIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ + struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ + void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ + struct xLIST * configLIST_VOLATILE pxContainer; /*< Pointer to the list in which this list item is placed (if any). */ + listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +}; +typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ + +struct xMINI_LIST_ITEM +{ + listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + configLIST_VOLATILE TickType_t xItemValue; + struct xLIST_ITEM * configLIST_VOLATILE pxNext; + struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; +}; +typedef struct xMINI_LIST_ITEM MiniListItem_t; + +/* + * Definition of the type of queue used by the scheduler. + */ +typedef struct xLIST +{ + listFIRST_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ + volatile UBaseType_t uxNumberOfItems; + ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ + MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ + listSECOND_LIST_INTEGRITY_CHECK_VALUE /*< Set to a known value if configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES is set to 1. */ +} List_t; + +/* + * Access macro to set the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_OWNER( pxListItem, pxOwner ) ( ( pxListItem )->pvOwner = ( void * ) ( pxOwner ) ) + +/* + * Access macro to get the owner of a list item. The owner of a list item + * is the object (usually a TCB) that contains the list item. + * + * \page listSET_LIST_ITEM_OWNER listSET_LIST_ITEM_OWNER + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_OWNER( pxListItem ) ( ( pxListItem )->pvOwner ) + +/* + * Access macro to set the value of the list item. In most cases the value is + * used to sort the list in descending order. + * + * \page listSET_LIST_ITEM_VALUE listSET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listSET_LIST_ITEM_VALUE( pxListItem, xValue ) ( ( pxListItem )->xItemValue = ( xValue ) ) + +/* + * Access macro to retrieve the value of the list item. The value can + * represent anything - for example the priority of a task, or the time at + * which a task should be unblocked. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_LIST_ITEM_VALUE( pxListItem ) ( ( pxListItem )->xItemValue ) + +/* + * Access macro to retrieve the value of the list item at the head of a given + * list. + * + * \page listGET_LIST_ITEM_VALUE listGET_LIST_ITEM_VALUE + * \ingroup LinkedList + */ +#define listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext->xItemValue ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_HEAD_ENTRY listGET_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_HEAD_ENTRY( pxList ) ( ( ( pxList )->xListEnd ).pxNext ) + +/* + * Return the list item at the head of the list. + * + * \page listGET_NEXT listGET_NEXT + * \ingroup LinkedList + */ +#define listGET_NEXT( pxListItem ) ( ( pxListItem )->pxNext ) + +/* + * Return the list item that marks the end of the list + * + * \page listGET_END_MARKER listGET_END_MARKER + * \ingroup LinkedList + */ +#define listGET_END_MARKER( pxList ) ( ( ListItem_t const * ) ( &( ( pxList )->xListEnd ) ) ) + +/* + * Access macro to determine if a list contains any items. The macro will + * only have the value true if the list is empty. + * + * \page listLIST_IS_EMPTY listLIST_IS_EMPTY + * \ingroup LinkedList + */ +#define listLIST_IS_EMPTY( pxList ) ( ( ( pxList )->uxNumberOfItems == ( UBaseType_t ) 0 ) ? pdTRUE : pdFALSE ) + +/* + * Access macro to return the number of items in the list. + */ +#define listCURRENT_LIST_LENGTH( pxList ) ( ( pxList )->uxNumberOfItems ) + +/* + * Access function to obtain the owner of the next entry in a list. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list + * and returns that entry's pxOwner parameter. Using multiple calls to this + * function it is therefore possible to move through every item contained in + * a list. + * + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxTCB pxTCB is set to the address of the owner of the next list item. + * @param pxList The list from which the next item owner is to be returned. + * + * \page listGET_OWNER_OF_NEXT_ENTRY listGET_OWNER_OF_NEXT_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ +{ \ +List_t * const pxConstList = ( pxList ); \ + /* Increment the index to the next item and return the item, ensuring */ \ + /* we don't return the marker used at the end of the list. */ \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ + { \ + ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ + } \ + ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ +} + + +/* + * Access function to obtain the owner of the first entry in a list. Lists + * are normally sorted in ascending item value order. + * + * This function returns the pxOwner member of the first item in the list. + * The pxOwner parameter of a list item is a pointer to the object that owns + * the list item. In the scheduler this is normally a task control block. + * The pxOwner parameter effectively creates a two way link between the list + * item and its owner. + * + * @param pxList The list from which the owner of the head item is to be + * returned. + * + * \page listGET_OWNER_OF_HEAD_ENTRY listGET_OWNER_OF_HEAD_ENTRY + * \ingroup LinkedList + */ +#define listGET_OWNER_OF_HEAD_ENTRY( pxList ) ( (&( ( pxList )->xListEnd ))->pxNext->pvOwner ) + +/* + * Check to see if a list item is within a list. The list item maintains a + * "container" pointer that points to the list it is in. All this macro does + * is check to see if the container and the list match. + * + * @param pxList The list we want to know if the list item is within. + * @param pxListItem The list item we want to know if is in the list. + * @return pdTRUE if the list item is in the list, otherwise pdFALSE. + */ +#define listIS_CONTAINED_WITHIN( pxList, pxListItem ) ( ( ( pxListItem )->pxContainer == ( pxList ) ) ? ( pdTRUE ) : ( pdFALSE ) ) + +/* + * Return the list a list item is contained within (referenced from). + * + * @param pxListItem The list item being queried. + * @return A pointer to the List_t object that references the pxListItem + */ +#define listLIST_ITEM_CONTAINER( pxListItem ) ( ( pxListItem )->pxContainer ) + +/* + * This provides a crude means of knowing if a list has been initialised, as + * pxList->xListEnd.xItemValue is set to portMAX_DELAY by the vListInitialise() + * function. + */ +#define listLIST_IS_INITIALISED( pxList ) ( ( pxList )->xListEnd.xItemValue == portMAX_DELAY ) + +/* + * Must be called before a list is used! This initialises all the members + * of the list structure and inserts the xListEnd item into the list as a + * marker to the back of the list. + * + * @param pxList Pointer to the list being initialised. + * + * \page vListInitialise vListInitialise + * \ingroup LinkedList + */ +void vListInitialise( List_t * const pxList ) PRIVILEGED_FUNCTION; + +/* + * Must be called before a list item is used. This sets the list container to + * null so the item does not think that it is already contained in a list. + * + * @param pxItem Pointer to the list item being initialised. + * + * \page vListInitialiseItem vListInitialiseItem + * \ingroup LinkedList + */ +void vListInitialiseItem( ListItem_t * const pxItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted into the list in + * a position determined by its item value (descending item value order). + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The item that is to be placed in the list. + * + * \page vListInsert vListInsert + * \ingroup LinkedList + */ +void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Insert a list item into a list. The item will be inserted in a position + * such that it will be the last item within the list returned by multiple + * calls to listGET_OWNER_OF_NEXT_ENTRY. + * + * The list member pxIndex is used to walk through a list. Calling + * listGET_OWNER_OF_NEXT_ENTRY increments pxIndex to the next item in the list. + * Placing an item in a list using vListInsertEnd effectively places the item + * in the list position pointed to by pxIndex. This means that every other + * item within the list will be returned by listGET_OWNER_OF_NEXT_ENTRY before + * the pxIndex parameter again points to the item being inserted. + * + * @param pxList The list into which the item is to be inserted. + * + * @param pxNewListItem The list item to be inserted into the list. + * + * \page vListInsertEnd vListInsertEnd + * \ingroup LinkedList + */ +void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem ) PRIVILEGED_FUNCTION; + +/* + * Remove an item from a list. The list item has a pointer to the list that + * it is in, so only the list item need be passed into the function. + * + * @param uxListRemove The item to be removed. The item will remove itself from + * the list pointed to by it's pxContainer parameter. + * + * @return The number of items that remain in the list after the list item has + * been removed. + * + * \page uxListRemove uxListRemove + * \ingroup LinkedList + */ +UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove ) PRIVILEGED_FUNCTION; + +#ifdef __cplusplus +} +#endif + +#endif + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/message_buffer.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/message_buffer.h new file mode 100644 index 0000000..784fc31 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/message_buffer.h @@ -0,0 +1,800 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +/* + * Message buffers build functionality on top of FreeRTOS stream buffers. + * Whereas stream buffers are used to send a continuous stream of data from one + * task or interrupt to another, message buffers are used to send variable + * length discrete messages from one task or interrupt to another. Their + * implementation is light weight, making them particularly suited for interrupt + * to task and core to core communication scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * timeout to 0. + * + * Message buffers hold variable length messages. To enable that, when a + * message is written to the message buffer an additional sizeof( size_t ) bytes + * are also written to store the message's length (that happens internally, with + * the API function). sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so writing a 10 byte message to a message buffer on a 32-bit + * architecture will actually reduce the available space in the message buffer + * by 14 bytes (10 byte are used by the message, and 4 bytes to hold the length + * of the message). + */ + +#ifndef FREERTOS_MESSAGE_BUFFER_H +#define FREERTOS_MESSAGE_BUFFER_H + +/* Message buffers are built onto of stream buffers. */ +#include "stream_buffer.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which message buffers are referenced. For example, a call to + * xMessageBufferCreate() returns an MessageBufferHandle_t variable that can + * then be used as a parameter to xMessageBufferSend(), xMessageBufferReceive(), + * etc. + */ +typedef void * MessageBufferHandle_t; + +/*-----------------------------------------------------------*/ + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreate( size_t xBufferSizeBytes );
+
+ * + * Creates a new message buffer using dynamically allocated memory. See + * xMessageBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xMessageBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes (not messages) the message + * buffer will be able to hold at any one time. When a message is written to + * the message buffer an additional sizeof( size_t ) bytes are also written to + * store the message's length. sizeof( size_t ) is typically 4 bytes on a + * 32-bit architecture, so on most 32-bit architectures a 10 byte message will + * take up 14 bytes of message buffer space. + * + * @return If NULL is returned, then the message buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the message buffer data structures and storage area. A non-NULL value being + * returned indicates that the message buffer has been created successfully - + * the returned value should be stored as the handle to the created message + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+const size_t xMessageBufferSizeBytes = 100;
+
+    // Create a message buffer that can hold 100 bytes.  The memory used to hold
+    // both the message buffer structure and the messages themselves is allocated
+    // dynamically.  Each message added to the buffer consumes an additional 4
+    // bytes which are used to hold the lengh of the message.
+    xMessageBuffer = xMessageBufferCreate( xMessageBufferSizeBytes );
+
+    if( xMessageBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // message buffer.
+    }
+    else
+    {
+        // The message buffer was created successfully and can now be used.
+    }
+
+
+ * \defgroup xMessageBufferCreate xMessageBufferCreate + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreate( xBufferSizeBytes ) ( MessageBufferHandle_t ) xStreamBufferGenericCreate( xBufferSizeBytes, ( size_t ) 0, pdTRUE ) + +/** + * message_buffer.h + * +
+MessageBufferHandle_t xMessageBufferCreateStatic( size_t xBufferSizeBytes,
+                                                  uint8_t *pucMessageBufferStorageArea,
+                                                  StaticMessageBuffer_t *pxStaticMessageBuffer );
+
+ * Creates a new message buffer using statically allocated memory. See + * xMessageBufferCreate() for a version that uses dynamically allocated memory. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucMessageBufferStorageArea parameter. When a message is written to the + * message buffer an additional sizeof( size_t ) bytes are also written to store + * the message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so on most 32-bit architecture a 10 byte message will take up + * 14 bytes of message buffer space. The maximum number of bytes that can be + * stored in the message buffer is actually (xBufferSizeBytes - 1). + * + * @param pucMessageBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which messages are + * copied when they are written to the message buffer. + * + * @param pxStaticMessageBuffer Must point to a variable of type + * StaticMessageBuffer_t, which will be used to hold the message buffer's data + * structure. + * + * @return If the message buffer is created successfully then a handle to the + * created message buffer is returned. If either pucMessageBufferStorageArea or + * pxStaticmessageBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the messages.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the messages within the message
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the message buffer structure.
+StaticMessageBuffer_t xMessageBufferStruct;
+
+void MyFunction( void )
+{
+MessageBufferHandle_t xMessageBuffer;
+
+    xMessageBuffer = xMessageBufferCreateStatic( sizeof( ucBufferStorage ),
+                                                 ucBufferStorage,
+                                                 &xMessageBufferStruct );
+
+    // As neither the pucMessageBufferStorageArea or pxStaticMessageBuffer
+    // parameters were NULL, xMessageBuffer will not be NULL, and can be used to
+    // reference the created message buffer in other message buffer API calls.
+
+    // Other code that uses the message buffer can go here.
+}
+
+
+ * \defgroup xMessageBufferCreateStatic xMessageBufferCreateStatic + * \ingroup MessageBufferManagement + */ +#define xMessageBufferCreateStatic( xBufferSizeBytes, pucMessageBufferStorageArea, pxStaticMessageBuffer ) ( MessageBufferHandle_t ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, 0, pdTRUE, pucMessageBufferStorageArea, pxStaticMessageBuffer ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSend( MessageBufferHandle_t xMessageBuffer,
+                           const void *pvTxData,
+                           size_t xDataLengthBytes,
+                           TickType_t xTicksToWait );
+
+ *
+ * Sends a discrete message to the message buffer.  The message can be any
+ * length that fits within the buffer's free space, and is copied into the
+ * buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param xTicksToWait The maximum amount of time the calling task should remain
+ * in the Blocked state to wait for enough space to become available in the
+ * message buffer, should the message buffer have insufficient space when
+ * xMessageBufferSend() is called.  The calling task will never block if
+ * xTicksToWait is zero.  The block time is specified in tick periods, so the
+ * absolute time it represents is dependent on the tick frequency.  The macro
+ * pdMS_TO_TICKS() can be used to convert a time specified in milliseconds into
+ * a time specified in ticks.  Setting xTicksToWait to portMAX_DELAY will cause
+ * the task to wait indefinitely (without timing out), provided
+ * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h.  Tasks do not use any
+ * CPU time when they are in the Blocked state.
+ *
+ * @return The number of bytes written to the message buffer.  If the call to
+ * xMessageBufferSend() times out before there was enough space to write the
+ * message into the message buffer then zero is returned.  If the call did not
+ * time out then xDataLengthBytes is returned.
+ *
+ * Example use:
+
+void vAFunction( MessageBufferHandle_t xMessageBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the message buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the message buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xMessageBufferSend() times out before there was enough
+        // space in the buffer for the data to be written.
+    }
+
+    // Send the string to the message buffer.  Return immediately if there is
+    // not enough space in the buffer.
+    xBytesSent = xMessageBufferSend( xMessageBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+}
+
+ * \defgroup xMessageBufferSend xMessageBufferSend + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSend( xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) xStreamBufferSend( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, xTicksToWait ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferSendFromISR( MessageBufferHandle_t xMessageBuffer,
+                                  const void *pvTxData,
+                                  size_t xDataLengthBytes,
+                                  BaseType_t *pxHigherPriorityTaskWoken );
+
+ *
+ * Interrupt safe version of the API function that sends a discrete message to
+ * the message buffer.  The message can be any length that fits within the
+ * buffer's free space, and is copied into the buffer.
+ *
+ * ***NOTE***:  Uniquely among FreeRTOS objects, the stream buffer
+ * implementation (so also the message buffer implementation, as message buffers
+ * are built on top of stream buffers) assumes there is only one task or
+ * interrupt that will write to the buffer (the writer), and only one task or
+ * interrupt that will read from the buffer (the reader).  It is safe for the
+ * writer and reader to be different tasks or interrupts, but, unlike other
+ * FreeRTOS objects, it is not safe to have multiple different writers or
+ * multiple different readers.  If there are to be multiple different writers
+ * then the application writer must place each call to a writing API function
+ * (such as xMessageBufferSend()) inside a critical section and set the send
+ * block time to 0.  Likewise, if there are to be multiple different readers
+ * then the application writer must place each call to a reading API function
+ * (such as xMessageBufferRead()) inside a critical section and set the receive
+ * block time to 0.
+ *
+ * Use xMessageBufferSend() to write to a message buffer from a task.  Use
+ * xMessageBufferSendFromISR() to write to a message buffer from an interrupt
+ * service routine (ISR).
+ *
+ * @param xMessageBuffer The handle of the message buffer to which a message is
+ * being sent.
+ *
+ * @param pvTxData A pointer to the message that is to be copied into the
+ * message buffer.
+ *
+ * @param xDataLengthBytes The length of the message.  That is, the number of
+ * bytes to copy from pvTxData into the message buffer.  When a message is
+ * written to the message buffer an additional sizeof( size_t ) bytes are also
+ * written to store the message's length.  sizeof( size_t ) is typically 4 bytes
+ * on a 32-bit architecture, so on most 32-bit architecture setting
+ * xDataLengthBytes to 20 will reduce the free space in the message buffer by 24
+ * bytes (20 bytes of message data and 4 bytes to hold the message length).
+ *
+ * @param pxHigherPriorityTaskWoken  It is possible that a message buffer will
+ * have a task blocked on it waiting for data.  Calling
+ * xMessageBufferSendFromISR() can make data available, and so cause a task that
+ * was waiting for data to leave the Blocked state.  If calling
+ * xMessageBufferSendFromISR() causes a task to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently executing task (the
+ * task that was interrupted), then, internally, xMessageBufferSendFromISR()
+ * will set *pxHigherPriorityTaskWoken to pdTRUE.  If
+ * xMessageBufferSendFromISR() sets this value to pdTRUE, then normally a
+ * context switch should be performed before the interrupt is exited.  This will
+ * ensure that the interrupt returns directly to the highest priority Ready
+ * state task.  *pxHigherPriorityTaskWoken should be set to pdFALSE before it
+ * is passed into the function.  See the code example below for an example.
+ *
+ * @return The number of bytes actually written to the message buffer.  If the
+ * message buffer didn't have enough free space for the message to be stored
+ * then 0 is returned, otherwise xDataLengthBytes is returned.
+ *
+ * Example use:
+
+// A message buffer that has already been created.
+MessageBufferHandle_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the message buffer.
+    xBytesSent = xMessageBufferSendFromISR( xMessageBuffer,
+                                            ( void * ) pcStringToSend,
+                                            strlen( pcStringToSend ),
+                                            &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The string could not be added to the message buffer because there was
+        // not enough free space in the buffer.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferSendFromISR xMessageBufferSendFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSendFromISR( xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferSendFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvTxData, xDataLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceive( MessageBufferHandle_t xMessageBuffer,
+                              void *pvRxData,
+                              size_t xBufferLengthBytes,
+                              TickType_t xTicksToWait );
+
+ * + * Receives a discrete message from a message buffer. Messages can be of + * variable length and are copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for a message, should the message buffer be empty. + * xMessageBufferReceive() will return immediately if xTicksToWait is zero and + * the message buffer is empty. The block time is specified in tick periods, so + * the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. Tasks do not use any + * CPU time when they are in the Blocked state. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. If xMessageBufferReceive() times out before a message became available + * then zero is returned. If the length of the message is greater than + * xBufferLengthBytes then the message will be left in the message buffer and + * zero is returned. + * + * Example use: +
+void vAFunction( MessageBuffer_t xMessageBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive the next message from the message buffer.  Wait in the Blocked
+    // state (so not using any CPU processing time) for a maximum of 100ms for
+    // a message to become available.
+    xReceivedBytes = xMessageBufferReceive( xMessageBuffer,
+                                            ( void * ) ucRxData,
+                                            sizeof( ucRxData ),
+                                            xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+}
+
+ * \defgroup xMessageBufferReceive xMessageBufferReceive + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceive( xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) xStreamBufferReceive( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ) + + +/** + * message_buffer.h + * +
+size_t xMessageBufferReceiveFromISR( MessageBufferHandle_t xMessageBuffer,
+                                     void *pvRxData,
+                                     size_t xBufferLengthBytes,
+                                     BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives a discrete + * message from a message buffer. Messages can be of variable length and are + * copied out of the buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xMessageBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xMessageBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xMessageBufferReceive() to read from a message buffer from a task. Use + * xMessageBufferReceiveFromISR() to read from a message buffer from an + * interrupt service routine (ISR). + * + * @param xMessageBuffer The handle of the message buffer from which a message + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received message is + * to be copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the pvRxData + * parameter. This sets the maximum length of the message that can be received. + * If xBufferLengthBytes is too small to hold the next message then the message + * will be left in the message buffer and 0 will be returned. + * + * @param pxHigherPriorityTaskWoken It is possible that a message buffer will + * have a task blocked on it waiting for space to become available. Calling + * xMessageBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xMessageBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xMessageBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xMessageBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The length, in bytes, of the message read from the message buffer, if + * any. + * + * Example use: +
+// A message buffer that has already been created.
+MessageBuffer_t xMessageBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next message from the message buffer.
+    xReceivedBytes = xMessageBufferReceiveFromISR( xMessageBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains a message that is xReceivedBytes long.  Process
+        // the message here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xMessageBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xMessageBufferReceiveFromISR xMessageBufferReceiveFromISR + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReceiveFromISR( xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) xStreamBufferReceiveFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pvRxData, xBufferLengthBytes, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+void vMessageBufferDelete( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Deletes a message buffer that was previously created using a call to + * xMessageBufferCreate() or xMessageBufferCreateStatic(). If the message + * buffer was created using dynamic memory (that is, by xMessageBufferCreate()), + * then the allocated memory is freed. + * + * A message buffer handle must not be used after the message buffer has been + * deleted. + * + * @param xMessageBuffer The handle of the message buffer to be deleted. + * + */ +#define vMessageBufferDelete( xMessageBuffer ) vStreamBufferDelete( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsFull( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is full. A message buffer is full if it + * cannot accept any more messages, of any size, until space is made available + * by a message being removed from the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is full then + * pdTRUE is returned. Otherwise pdFALSE is returned. + */ +#define xMessageBufferIsFull( xMessageBuffer ) xStreamBufferIsFull( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferIsEmpty( MessageBufferHandle_t xMessageBuffer ) );
+
+ * + * Tests to see if a message buffer is empty (does not contain any messages). + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return If the message buffer referenced by xMessageBuffer is empty then + * pdTRUE is returned. Otherwise pdFALSE is returned. + * + */ +#define xMessageBufferIsEmpty( xMessageBuffer ) xStreamBufferIsEmpty( ( StreamBufferHandle_t ) xMessageBuffer ) + +/** + * message_buffer.h +
+BaseType_t xMessageBufferReset( MessageBufferHandle_t xMessageBuffer );
+
+ * + * Resets a message buffer to its initial empty state, discarding any message it + * contained. + * + * A message buffer can only be reset if there are no tasks blocked on it. + * + * @param xMessageBuffer The handle of the message buffer being reset. + * + * @return If the message buffer was reset then pdPASS is returned. If the + * message buffer could not be reset because either there was a task blocked on + * the message queue to wait for space to become available, or to wait for a + * a message to be available, then pdFAIL is returned. + * + * \defgroup xMessageBufferReset xMessageBufferReset + * \ingroup MessageBufferManagement + */ +#define xMessageBufferReset( xMessageBuffer ) xStreamBufferReset( ( StreamBufferHandle_t ) xMessageBuffer ) + + +/** + * message_buffer.h +
+size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
+
+ * Returns the number of bytes of free space in the message buffer. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The number of bytes that can be written to the message buffer before + * the message buffer would be full. When a message is written to the message + * buffer an additional sizeof( size_t ) bytes are also written to store the + * message's length. sizeof( size_t ) is typically 4 bytes on a 32-bit + * architecture, so if xMessageBufferSpacesAvailable() returns 10, then the size + * of the largest message that can be written to the message buffer is 6 bytes. + * + * \defgroup xMessageBufferSpaceAvailable xMessageBufferSpaceAvailable + * \ingroup MessageBufferManagement + */ +#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) +#define xMessageBufferSpacesAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer ) /* Corrects typo in original macro name. */ + +/** + * message_buffer.h +
+ size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
+ 
+ * Returns the length (in bytes) of the next message in a message buffer. + * Useful if xMessageBufferReceive() returned 0 because the size of the buffer + * passed into xMessageBufferReceive() was too small to hold the next message. + * + * @param xMessageBuffer The handle of the message buffer being queried. + * + * @return The length (in bytes) of the next message in the message buffer, or 0 + * if the message buffer is empty. + * + * \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes + * \ingroup MessageBufferManagement + */ +#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION; + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferSendCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xMessageBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferSendCompletedFromISR(). If calling + * xMessageBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferSendCompletedFromISR xMessageBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferSendCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferSendCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +/** + * message_buffer.h + * +
+BaseType_t xMessageBufferReceiveCompletedFromISR( MessageBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xMessageBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xMessageBufferReceiveCompletedFromISR(). If calling + * xMessageBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xMessageBufferReceiveCompletedFromISR xMessageBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +#define xMessageBufferReceiveCompletedFromISR( xMessageBuffer, pxHigherPriorityTaskWoken ) xStreamBufferReceiveCompletedFromISR( ( StreamBufferHandle_t ) xMessageBuffer, pxHigherPriorityTaskWoken ) + +#if defined( __cplusplus ) +} /* extern "C" */ +#endif + +#endif /* !defined( FREERTOS_MESSAGE_BUFFER_H ) */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_prototypes.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_prototypes.h new file mode 100644 index 0000000..900111e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_prototypes.h @@ -0,0 +1,158 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * When the MPU is used the standard (non MPU) API functions are mapped to + * equivalents that start "MPU_", the prototypes for which are defined in this + * header files. This will cause the application code to call the MPU_ version + * which wraps the non-MPU version with privilege promoting then demoting code, + * so the kernel code always runs will full privileges. + */ + + +#ifndef MPU_PROTOTYPES_H +#define MPU_PROTOTYPES_H + +/* MPU versions of tasks.h API functions. */ +BaseType_t MPU_xTaskCreate( TaskFunction_t pxTaskCode, const char * const pcName, const uint16_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pxCreatedTask ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelete( TaskHandle_t xTaskToDelete ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelay( const TickType_t xTicksToDelay ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +eTaskState MPU_eTaskGetState( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspend( TaskHandle_t xTaskToSuspend ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskResume( TaskHandle_t xTaskToResume ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskStartScheduler( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSuspendAll( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskResumeAll( void ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetTickCount( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) FREERTOS_SYSTEM_CALL; +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) FREERTOS_SYSTEM_CALL; +TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskList( char * pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskIncrementTick( void ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vTaskMissedYield( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTaskGetSchedulerState( void ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of queue.h API functions. */ +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueDelete( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcQueueGetName( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) FREERTOS_SYSTEM_CALL; +QueueSetHandle_t MPU_xQueueCreateSet( const UBaseType_t uxEventQueueLength ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) FREERTOS_SYSTEM_CALL; +QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) FREERTOS_SYSTEM_CALL; +void MPU_vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxQueueGetQueueNumber( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; +uint8_t MPU_ucQueueGetQueueType( QueueHandle_t xQueue ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of timers.h API functions. */ +TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) FREERTOS_SYSTEM_CALL; +TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) FREERTOS_SYSTEM_CALL; +void * MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerCreateTimerTask( void ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of event_group.h API functions. */ +EventGroupHandle_t MPU_xEventGroupCreate( void ) FREERTOS_SYSTEM_CALL; +EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) FREERTOS_SYSTEM_CALL; +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) FREERTOS_SYSTEM_CALL; +UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup ) FREERTOS_SYSTEM_CALL; + +/* MPU versions of message/stream_buffer.h API functions. */ +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) FREERTOS_SYSTEM_CALL; +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) FREERTOS_SYSTEM_CALL; +StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) FREERTOS_SYSTEM_CALL; + + + +#endif /* MPU_PROTOTYPES_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.c new file mode 100644 index 0000000..f59350b --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.c @@ -0,0 +1,1342 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Implementation of the wrapper functions used to raise the processor privilege + * before calling a standard FreeRTOS API function. + */ + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" +#include "event_groups.h" +#include "stream_buffer.h" +#include "mpu_prototypes.h" + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#if configENABLE_MPU /* << EST: only compile this module if MPU is actually enabled and supported */ + +/** + * @brief Calls the port specific code to raise the privilege. + * + * @return pdFALSE if privilege was raised, pdTRUE otherwise. + */ +BaseType_t xPortRaisePrivilege( void ) FREERTOS_SYSTEM_CALL; + +/** + * @brief If xRunningPrivileged is not pdTRUE, calls the port specific + * code to reset the privilege, otherwise does nothing. + */ +void vPortResetPrivilege( BaseType_t xRunningPrivileged ); +/*-----------------------------------------------------------*/ + +BaseType_t xPortRaisePrivilege( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged; + + /* Check whether the processor is already privileged. */ + xRunningPrivileged = portIS_PRIVILEGED(); + + /* If the processor is not already privileged, raise privilege. */ + if( xRunningPrivileged != pdTRUE ) + { + portRAISE_PRIVILEGE(); + } + + return xRunningPrivileged; +} +/*-----------------------------------------------------------*/ + +void vPortResetPrivilege( BaseType_t xRunningPrivileged ) +{ + if( xRunningPrivileged != pdTRUE ) + { + portRESET_PRIVILEGE(); + } +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestricted( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateRestrictedStatic( pxTaskDefinition, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* conifgSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t MPU_xTaskCreate( TaskFunction_t pvTaskCode, const char * const pcName, uint16_t usStackDepth, void *pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t MPU_xTaskCreateStatic( TaskFunction_t pxTaskCode, const char * const pcName, const uint32_t ulStackDepth, void * const pvParameters, UBaseType_t uxPriority, StackType_t * const puxStackBuffer, StaticTask_t * const pxTaskBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCreateStatic( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, puxStackBuffer, pxTaskBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +void MPU_vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const xRegions ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskAllocateMPURegions( xTask, xRegions ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + void MPU_vTaskDelete( TaskHandle_t pxTaskToDelete ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelete( pxTaskToDelete ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + void MPU_vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, TickType_t xTimeIncrement ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + BaseType_t MPU_xTaskAbortDelay( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskAbortDelay( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + void MPU_vTaskDelay( TickType_t xTicksToDelay ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskDelay( xTicksToDelay ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + UBaseType_t MPU_uxTaskPriorityGet( const TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskPriorityGet( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + void MPU_vTaskPrioritySet( TaskHandle_t pxTask, UBaseType_t uxNewPriority ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskPrioritySet( pxTask, uxNewPriority ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_eTaskGetState == 1 ) + eTaskState MPU_eTaskGetState( TaskHandle_t pxTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + eTaskState eReturn; + + eReturn = eTaskGetState( pxTask ); + vPortResetPrivilege( xRunningPrivileged ); + return eReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + void MPU_vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetInfo( xTask, pxTaskStatus, xGetFreeStackSpace, eState ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetIdleTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskSuspend( TaskHandle_t pxTaskToSuspend ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspend( pxTaskToSuspend ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + void MPU_vTaskResume( TaskHandle_t pxTaskToResume ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskResume( pxTaskToResume ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSuspendAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSuspendAll(); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskResumeAll( void ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskResumeAll(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +TickType_t MPU_xTaskGetTickCount( void ) /* FREERTOS_SYSTEM_CALL */ +{ +TickType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetTickCount(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxTaskGetNumberOfTasks( void ) /* FREERTOS_SYSTEM_CALL */ +{ +UBaseType_t uxReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetNumberOfTasks(); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +char * MPU_pcTaskGetName( TaskHandle_t xTaskToQuery ) /* FREERTOS_SYSTEM_CALL */ +{ +char *pcReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTaskGetName( xTaskToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + TaskHandle_t MPU_xTaskGetHandle( const char *pcNameToQuery ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetHandle( pcNameToQuery ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskList( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskList( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + void MPU_vTaskGetRunTimeStats( char *pcWriteBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskGetRunTimeStats( pcWriteBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t MPU_xTaskGetIdleRunTimeCounter( void ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetIdleRunTimeCounter(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + void MPU_vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxTagValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetApplicationTaskTag( xTask, pxTagValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t MPU_xTaskGetApplicationTaskTag( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHookFunction_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetApplicationTaskTag( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void MPU_vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetThreadLocalStoragePointer( xTaskToSet, xIndex, pvValue ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + void *MPU_pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTaskGetThreadLocalStoragePointer( xTaskToQuery, xIndex ); + vPortResetPrivilege( xRunningPrivileged ); + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + BaseType_t MPU_xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t MPU_uxTaskGetSystemState( TaskStatus_t *pxTaskStatusArray, UBaseType_t uxArraySize, uint32_t *pulTotalRunTime ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, pulTotalRunTime ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + UBaseType_t MPU_uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + UBaseType_t uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + configSTACK_DEPTH_TYPE MPU_uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + configSTACK_DEPTH_TYPE uxReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + uxReturn = uxTaskGetStackHighWaterMark2( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) + TaskHandle_t MPU_xTaskGetCurrentTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetCurrentTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetSchedulerState == 1 ) + BaseType_t MPU_xTaskGetSchedulerState( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGetSchedulerState(); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTaskSetTimeOutState( pxTimeOut ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskCheckForTimeOut( pxTimeOut, pxTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskGenericNotify( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyWait( ulBitsToClearOnEntry, ulBitsToClearOnExit, pulNotificationValue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + uint32_t MPU_ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + uint32_t ulReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + ulReturn = ulTaskNotifyTake( xClearCountOnExit, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return ulReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + BaseType_t MPU_xTaskNotifyStateClear( TaskHandle_t xTask ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTaskNotifyStateClear( xTask ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreate( UBaseType_t uxQueueLength, UBaseType_t uxItemSize, uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t MPU_xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxStaticQueue, ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericReset( QueueHandle_t pxQueue, BaseType_t xNewQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericReset( pxQueue, xNewQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, BaseType_t xCopyPosition ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueMessagesWaiting( const QueueHandle_t pxQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueMessagesWaiting( pxQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t MPU_uxQueueSpacesAvailable( const QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +UBaseType_t uxReturn; + + uxReturn = uxQueueSpacesAvailable( xQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return uxReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueReceive( QueueHandle_t pxQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueReceive( pxQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueuePeek( xQueue, pvBuffer, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); +BaseType_t xReturn; + + xReturn = xQueueSemaphoreTake( xQueue, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + TaskHandle_t MPU_xQueueGetMutexHolder( QueueHandle_t xSemaphore ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + void * xReturn; + + xReturn = xQueueGetMutexHolder( xSemaphore ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutex( const uint8_t ucQueueType ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutex( ucQueueType ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateMutexStatic( ucQueueType, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueHandle_t MPU_xQueueCreateCountingSemaphore( UBaseType_t uxCountValue, UBaseType_t uxInitialCount ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t MPU_xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) /* FREERTOS_SYSTEM_CALL */ + { + QueueHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateCountingSemaphoreStatic( uxMaxCount, uxInitialCount, pxStaticQueue ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xBlockTime ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + BaseType_t MPU_xQueueGiveMutexRecursive( QueueHandle_t xMutex ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueGiveMutexRecursive( xMutex ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + QueueSetHandle_t MPU_xQueueCreateSet( UBaseType_t uxEventQueueLength ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueCreateSet( uxEventQueueLength ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + QueueSetMemberHandle_t MPU_xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t xBlockTimeTicks ) /* FREERTOS_SYSTEM_CALL */ + { + QueueSetMemberHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + BaseType_t MPU_xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet ); + vPortResetPrivilege( xRunningPrivileged ); + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcName ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueAddToRegistry( xQueue, pcName ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + void MPU_vQueueUnregisterQueue( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueUnregisterQueue( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if configQUEUE_REGISTRY_SIZE > 0 + const char *MPU_pcQueueGetName( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + const char *pcReturn; + + pcReturn = pcQueueGetName( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +void MPU_vQueueDelete( QueueHandle_t xQueue ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vQueueDelete( xQueue ); + + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void *MPU_pvPortMalloc( size_t xSize ) /* FREERTOS_SYSTEM_CALL */ + { + void *pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvPortMalloc( xSize ); + + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortFree( void *pv ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortFree( pv ); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + void MPU_vPortInitialiseBlocks( void ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vPortInitialiseBlocks(); + + vPortResetPrivilege( xRunningPrivileged ); + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + size_t MPU_xPortGetFreeHeapSize( void ) /* FREERTOS_SYSTEM_CALL */ + { + size_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xPortGetFreeHeapSize(); + + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreate( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreate( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_TIMERS == 1 ) ) + TimerHandle_t MPU_xTimerCreateStatic( const char * const pcTimerName, const TickType_t xTimerPeriodInTicks, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction, StaticTimer_t *pxTimerBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + TimerHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerCreateStatic( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxTimerBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void *MPU_pvTimerGetTimerID( const TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + void * pvReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pvReturn = pvTimerGetTimerID( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pvReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetTimerID( xTimer, pvNewID ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerIsTimerActive( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerIsTimerActive( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TaskHandle_t MPU_xTimerGetTimerDaemonTaskHandle( void ) /* FREERTOS_SYSTEM_CALL */ + { + TaskHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetTimerDaemonTaskHandle(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + BaseType_t MPU_xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerPendFunctionCall( xFunctionToPend, pvParameter1, ulParameter2, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + void MPU_vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vTimerSetReloadMode( xTimer, uxAutoReload ); + vPortResetPrivilege( xRunningPrivileged ); + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + const char * MPU_pcTimerGetName( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + const char * pcReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + pcReturn = pcTimerGetName( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return pcReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetPeriod( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetPeriod( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + TickType_t MPU_xTimerGetExpiryTime( TimerHandle_t xTimer ) /* FREERTOS_SYSTEM_CALL */ + { + TickType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGetExpiryTime( xTimer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + BaseType_t MPU_xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ + { + BaseType_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xTimerGenericCommand( xTimer, xCommandID, xOptionalValue, pxHigherPriorityTaskWoken, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreate( void ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreate(); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + EventGroupHandle_t MPU_xEventGroupCreateStatic( StaticEventGroup_t *pxEventGroupBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + EventGroupHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupCreateStatic( pxEventGroupBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupWaitBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToWaitFor, const BaseType_t xClearOnExit, const BaseType_t xWaitForAllBits, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupWaitBits( xEventGroup, uxBitsToWaitFor, xClearOnExit, xWaitForAllBits, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupClearBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupClearBits( xEventGroup, uxBitsToClear ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSetBits( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSetBits( xEventGroup, uxBitsToSet ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +EventBits_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xEventGroupSync( xEventGroup, uxBitsToSet, uxBitsToWaitFor, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vEventGroupDelete( EventGroupHandle_t xEventGroup ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vEventGroupDelete( xEventGroup ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSend( xStreamBuffer, pvTxData, xDataLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferNextMessageLengthBytes( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReceive( xStreamBuffer, pvRxData, xBufferLengthBytes, xTicksToWait ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + vStreamBufferDelete( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsFull( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferIsEmpty( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferReset( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSpacesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t MPU_xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ +{ +size_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferBytesAvailable( xStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t MPU_xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) /* FREERTOS_SYSTEM_CALL */ +{ +BaseType_t xReturn; +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferSetTriggerLevel( xStreamBuffer, xTriggerLevel ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + StreamBufferHandle_t MPU_xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer, uint8_t * const pucStreamBufferStorageArea, StaticStreamBuffer_t * const pxStaticStreamBuffer ) /* FREERTOS_SYSTEM_CALL */ + { + StreamBufferHandle_t xReturn; + BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + xReturn = xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, xIsMessageBuffer, pucStreamBufferStorageArea, pxStaticStreamBuffer ); + vPortResetPrivilege( xRunningPrivileged ); + + return xReturn; + } +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + + +/* Functions that the application writer wants to execute in privileged mode +can be defined in application_defined_privileged_functions.h. The functions +must take the same format as those above whereby the privilege state on exit +equals the privilege state on entry. For example: + +void MPU_FunctionName( [parameters ] ) +{ +BaseType_t xRunningPrivileged = xPortRaisePrivilege(); + + FunctionName( [parameters ] ); + + vPortResetPrivilege( xRunningPrivileged ); +} +*/ + +#if configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS == 1 + #include "application_defined_privileged_functions.h" +#endif + +#endif /* configENABLE_MPU */ /* << EST: only compile this module if MPU is actually enabled and supported */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.h new file mode 100644 index 0000000..b65f6b0 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/mpu_wrappers.h @@ -0,0 +1,187 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef MPU_WRAPPERS_H +#define MPU_WRAPPERS_H + +/* This file redefines API functions to be called through a wrapper macro, but +only for ports that are using the MPU. */ +#ifdef portUSING_MPU_WRAPPERS + + /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE will be defined when this file is + included from queue.c or task.c to prevent it from having an effect within + those files. */ + #ifndef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + + /* + * Map standard (non MPU) API functions to equivalents that start + * "MPU_". This will cause the application code to call the MPU_ + * version, which wraps the non-MPU version with privilege promoting + * then demoting code, so the kernel code always runs will full + * privileges. + */ + + /* Map standard tasks.h API functions to the MPU equivalents. */ + #define xTaskCreate MPU_xTaskCreate + #define xTaskCreateStatic MPU_xTaskCreateStatic + #define xTaskCreateRestricted MPU_xTaskCreateRestricted + #define vTaskAllocateMPURegions MPU_vTaskAllocateMPURegions + #define vTaskDelete MPU_vTaskDelete + #define vTaskDelay MPU_vTaskDelay + #define vTaskDelayUntil MPU_vTaskDelayUntil + #define xTaskAbortDelay MPU_xTaskAbortDelay + #define uxTaskPriorityGet MPU_uxTaskPriorityGet + #define eTaskGetState MPU_eTaskGetState + #define vTaskGetInfo MPU_vTaskGetInfo + #define vTaskPrioritySet MPU_vTaskPrioritySet + #define vTaskSuspend MPU_vTaskSuspend + #define vTaskResume MPU_vTaskResume + #define vTaskSuspendAll MPU_vTaskSuspendAll + #define xTaskResumeAll MPU_xTaskResumeAll + #define xTaskGetTickCount MPU_xTaskGetTickCount + #define uxTaskGetNumberOfTasks MPU_uxTaskGetNumberOfTasks + #define pcTaskGetName MPU_pcTaskGetName + #define xTaskGetHandle MPU_xTaskGetHandle + #define uxTaskGetStackHighWaterMark MPU_uxTaskGetStackHighWaterMark + #define uxTaskGetStackHighWaterMark2 MPU_uxTaskGetStackHighWaterMark2 + #define vTaskSetApplicationTaskTag MPU_vTaskSetApplicationTaskTag + #define xTaskGetApplicationTaskTag MPU_xTaskGetApplicationTaskTag + #define vTaskSetThreadLocalStoragePointer MPU_vTaskSetThreadLocalStoragePointer + #define pvTaskGetThreadLocalStoragePointer MPU_pvTaskGetThreadLocalStoragePointer + #define xTaskCallApplicationTaskHook MPU_xTaskCallApplicationTaskHook + #define xTaskGetIdleTaskHandle MPU_xTaskGetIdleTaskHandle + #define uxTaskGetSystemState MPU_uxTaskGetSystemState + #define vTaskList MPU_vTaskList + #define vTaskGetRunTimeStats MPU_vTaskGetRunTimeStats + #define xTaskGetIdleRunTimeCounter MPU_xTaskGetIdleRunTimeCounter + #define xTaskGenericNotify MPU_xTaskGenericNotify + #define xTaskNotifyWait MPU_xTaskNotifyWait + #define ulTaskNotifyTake MPU_ulTaskNotifyTake + #define xTaskNotifyStateClear MPU_xTaskNotifyStateClear + + #define xTaskGetCurrentTaskHandle MPU_xTaskGetCurrentTaskHandle + #define vTaskSetTimeOutState MPU_vTaskSetTimeOutState + #define xTaskCheckForTimeOut MPU_xTaskCheckForTimeOut + #define xTaskGetSchedulerState MPU_xTaskGetSchedulerState + + /* Map standard queue.h API functions to the MPU equivalents. */ + #define xQueueGenericSend MPU_xQueueGenericSend + #define xQueueReceive MPU_xQueueReceive + #define xQueuePeek MPU_xQueuePeek + #define xQueueSemaphoreTake MPU_xQueueSemaphoreTake + #define uxQueueMessagesWaiting MPU_uxQueueMessagesWaiting + #define uxQueueSpacesAvailable MPU_uxQueueSpacesAvailable + #define vQueueDelete MPU_vQueueDelete + #define xQueueCreateMutex MPU_xQueueCreateMutex + #define xQueueCreateMutexStatic MPU_xQueueCreateMutexStatic + #define xQueueCreateCountingSemaphore MPU_xQueueCreateCountingSemaphore + #define xQueueCreateCountingSemaphoreStatic MPU_xQueueCreateCountingSemaphoreStatic + #define xQueueGetMutexHolder MPU_xQueueGetMutexHolder + #define xQueueTakeMutexRecursive MPU_xQueueTakeMutexRecursive + #define xQueueGiveMutexRecursive MPU_xQueueGiveMutexRecursive + #define xQueueGenericCreate MPU_xQueueGenericCreate + #define xQueueGenericCreateStatic MPU_xQueueGenericCreateStatic + #define xQueueCreateSet MPU_xQueueCreateSet + #define xQueueAddToSet MPU_xQueueAddToSet + #define xQueueRemoveFromSet MPU_xQueueRemoveFromSet + #define xQueueSelectFromSet MPU_xQueueSelectFromSet + #define xQueueGenericReset MPU_xQueueGenericReset + + #if( configQUEUE_REGISTRY_SIZE > 0 ) + #define vQueueAddToRegistry MPU_vQueueAddToRegistry + #define vQueueUnregisterQueue MPU_vQueueUnregisterQueue + #define pcQueueGetName MPU_pcQueueGetName + #endif + + /* Map standard timer.h API functions to the MPU equivalents. */ + #define xTimerCreate MPU_xTimerCreate + #define xTimerCreateStatic MPU_xTimerCreateStatic + #define pvTimerGetTimerID MPU_pvTimerGetTimerID + #define vTimerSetTimerID MPU_vTimerSetTimerID + #define xTimerIsTimerActive MPU_xTimerIsTimerActive + #define xTimerGetTimerDaemonTaskHandle MPU_xTimerGetTimerDaemonTaskHandle + #define xTimerPendFunctionCall MPU_xTimerPendFunctionCall + #define pcTimerGetName MPU_pcTimerGetName + #define vTimerSetReloadMode MPU_vTimerSetReloadMode + #define xTimerGetPeriod MPU_xTimerGetPeriod + #define xTimerGetExpiryTime MPU_xTimerGetExpiryTime + #define xTimerGenericCommand MPU_xTimerGenericCommand + + /* Map standard event_group.h API functions to the MPU equivalents. */ + #define xEventGroupCreate MPU_xEventGroupCreate + #define xEventGroupCreateStatic MPU_xEventGroupCreateStatic + #define xEventGroupWaitBits MPU_xEventGroupWaitBits + #define xEventGroupClearBits MPU_xEventGroupClearBits + #define xEventGroupSetBits MPU_xEventGroupSetBits + #define xEventGroupSync MPU_xEventGroupSync + #define vEventGroupDelete MPU_vEventGroupDelete + + /* Map standard message/stream_buffer.h API functions to the MPU + equivalents. */ + #define xStreamBufferSend MPU_xStreamBufferSend + #define xStreamBufferReceive MPU_xStreamBufferReceive + #define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes + #define vStreamBufferDelete MPU_vStreamBufferDelete + #define xStreamBufferIsFull MPU_xStreamBufferIsFull + #define xStreamBufferIsEmpty MPU_xStreamBufferIsEmpty + #define xStreamBufferReset MPU_xStreamBufferReset + #define xStreamBufferSpacesAvailable MPU_xStreamBufferSpacesAvailable + #define xStreamBufferBytesAvailable MPU_xStreamBufferBytesAvailable + #define xStreamBufferSetTriggerLevel MPU_xStreamBufferSetTriggerLevel + #define xStreamBufferGenericCreate MPU_xStreamBufferGenericCreate + #define xStreamBufferGenericCreateStatic MPU_xStreamBufferGenericCreateStatic + + + /* Remove the privileged function macro, but keep the PRIVILEGED_DATA + macro so applications can place data in privileged access sections + (useful when using statically allocated objects). */ + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL + + #else /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + + /* Ensure API functions go in the privileged execution section. */ + #define PRIVILEGED_FUNCTION __attribute__((section("privileged_functions"))) + #define PRIVILEGED_DATA __attribute__((section("privileged_data"))) + #define FREERTOS_SYSTEM_CALL __attribute__((section( "freertos_system_calls"))) + + #endif /* MPU_WRAPPERS_INCLUDED_FROM_API_FILE */ + +#else /* portUSING_MPU_WRAPPERS */ + + #define PRIVILEGED_FUNCTION + #define PRIVILEGED_DATA + #define FREERTOS_SYSTEM_CALL + #define portUSING_MPU_WRAPPERS 0 + +#endif /* portUSING_MPU_WRAPPERS */ + + +#endif /* MPU_WRAPPERS_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/port.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/port.c new file mode 100644 index 0000000..dc5e9f6 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/port.c @@ -0,0 +1,1704 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * FreeRTOS for 56800EX port by Richy Ye in Jan. 2013. + *----------------------------------------------------------*/ +/* Scheduler includes. */ +#include "FreeRTOS.h" +#if MCUC1_CONFIG_SDK_USE_FREERTOS + +#include "portmacro.h" /* for configCPU_FAMILY */ +#include "task.h" +#include "portTicks.h" /* for CPU_CORE_CLK_HZ used in configSYSTICK_CLOCK_HZ */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if MCUC1_CONFIG_NXP_SDK_2_0_USED + #include "fsl_lptmr.h" /* SDK low power timer interface */ + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "LPTMR_PDD.h" /* PDD interface to low power timer */ + #include "SIM_PDD.h" /* PDD interface to system integration module */ + #endif +#endif + +#include "MCUC1.h" /* include SDK and API used */ +#if MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M + +#if( configENABLE_TRUSTZONE == 1 ) + /* Secure components includes. */ + #include "secure_context.h" + #include "secure_init.h" +#endif /* configENABLE_TRUSTZONE */ + +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/** + * The FreeRTOS Cortex M33 port can be configured to run on the Secure Side only + * i.e. the processor boots as secure and never jumps to the non-secure side. + * The Trust Zone support in the port must be disabled in order to run FreeRTOS + * on the secure side. The following are the valid configuration seetings: + * + * 1. Run FreeRTOS on the Secure Side: + * configRUN_FREERTOS_SECURE_ONLY = 1 and configENABLE_TRUSTZONE = 0 + * + * 2. Run FreeRTOS on the Non-Secure Side with Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 1 + * + * 3. Run FreeRTOS on the Non-Secure Side only i.e. no Secure Side function call support: + * configRUN_FREERTOS_SECURE_ONLY = 0 and configENABLE_TRUSTZONE = 0 + */ +#if( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) ) + #error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side. +#endif + +#endif /* MCUC1_CONFIG_CPU_IS_ARM_CORTEX_M */ +/* --------------------------------------------------- */ +/* Let the user override the pre-loading of the initial LR with the address of + prvTaskExitError() in case is messes up unwinding of the stack in the + debugger. */ +#ifdef configTASK_RETURN_ADDRESS + #define portTASK_RETURN_ADDRESS configTASK_RETURN_ADDRESS +#else + #define portTASK_RETURN_ADDRESS prvTaskExitError +#endif +/* --------------------------------------------------- */ +/* macros dealing with tick counter */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #if !MCUC1_CONFIG_PEX_SDK_USED + /*! \todo */ + #define LPTMR0_BASE_PTR LPTMR0 /* low power timer address base */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LPTMR0_IRQn /* low power timer IRQ number */ + #define ENABLE_TICK_COUNTER() LPTMR_StartTimer(LPTMR0_BASE_PTR); LPTMR_EnableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define DISABLE_TICK_COUNTER() LPTMR_StopTimer(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() LPTMR_StopTimer(LPTMR0_BASE_PTR); LPTMR_DisableInterrupts(LPTMR0_BASE_PTR, kLPTMR_TimerInterruptEnable) + #define ACKNOWLEDGE_TICK_ISR() LPTMR_ClearStatusFlags(LPTMR0_BASE_PTR, kLPTMR_TimerCompareFlag); + #elif MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #define ENABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_ENABLE); LPTMR_PDD_EnableInterrupt(LPTMR0_BASE_PTR) + #define DISABLE_TICK_COUNTER() LPTMR_PDD_EnableDevice(LPTMR0_BASE_PTR, PDD_DISABLE); LPTMR_PDD_DisableInterrupt(LPTMR0_BASE_PTR) + #define RESET_TICK_COUNTER_VAL() DISABLE_TICK_COUNTER() /* CNR is reset when the LPTMR is disabled or counter register overflows */ + #define ACKNOWLEDGE_TICK_ISR() LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR) + #if defined(LDD_ivIndex_INT_LPTimer) /* Earlier version of Processor Expert use this vector name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTimer + #elif defined(LDD_ivIndex_INT_LPTMR0) /* Newer versions (Processor Expert for Kinetis v3.0.1 uses this name */ + #define configLOW_POWER_TIMER_VECTOR_NUMBER LDD_ivIndex_INT_LPTMR0 + #else + #error "Unknown Low Power Timer Interrupt Number?" + #endif + #endif +#else + #define ENABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT + #define DISABLE_TICK_COUNTER() portNVIC_SYSTICK_CTRL_REG = portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT + #define RESET_TICK_COUNTER_VAL() portNVIC_SYSTICK_CURRENT_VALUE_REG = 0 /*portNVIC_SYSTICK_LOAD_REG*/ + #define ACKNOWLEDGE_TICK_ISR() /* not needed */ +#endif + +typedef unsigned long TickCounter_t; /* enough for 24 bit Systick */ +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TICK_NOF_BITS 16 + #define COUNTS_UP 1 /* LPTMR is counting up */ + #if !MCUC1_CONFIG_PEX_SDK_USED + #define SET_TICK_DURATION(val) LPTMR_SetTimerPeriod(LPTMR0_BASE_PTR, val); + #define GET_TICK_DURATION() LPTMR0_BASE_PTR->CNR /*! \todo SDK has no access method for this */ + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_GetCurrentTimerCount(LPTMR0_BASE_PTR) + #else + #define SET_TICK_DURATION(val) LPTMR_PDD_WriteCompareReg(LPTMR0_BASE_PTR, val) + #define GET_TICK_DURATION() LPTMR_PDD_ReadCompareReg(LPTMR0_BASE_PTR) + #define GET_TICK_CURRENT_VAL(addr) *(addr)=LPTMR_PDD_ReadCounterReg(LPTMR0_BASE_PTR) + #endif +#else + #define TICK_NOF_BITS 24 + #define COUNTS_UP 0 /* SysTick is counting down to zero */ + #define SET_TICK_DURATION(val) portNVIC_SYSTICK_LOAD_REG = val + #define GET_TICK_DURATION() portNVIC_SYSTICK_LOAD_REG + #define GET_TICK_CURRENT_VAL(addr) *(addr)=portNVIC_SYSTICK_CURRENT_VALUE_REG +#endif + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ/configTICK_RATE_HZ) +#else + #define TIMER_COUNTS_FOR_ONE_TICK (configSYSTICK_CLOCK_HZ/configTICK_RATE_HZ) +#endif + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + unsigned int SEGGER_SYSVIEW_TickCnt; /* tick counter for Segger SystemViewer */ +#endif + +#if configUSE_TICKLESS_IDLE + #define UL_TIMER_COUNTS_FOR_ONE_TICK ((TickCounter_t)(TIMER_COUNTS_FOR_ONE_TICK)) +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define TICKLESS_DISABLE_INTERRUPTS() __asm volatile("cpsid i") /* disable interrupts. Note that the wfi (wait for interrupt) instruction later will still be able to wait for interrupts! */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm volatile("cpsie i") /* re-enable interrupts. */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define TICKLESS_DISABLE_INTERRUPTS() __asm("sei"); /* disable interrupts */ + #define TICKLESS_ENABLE_INTERRUPTS() __asm("cli"); /* re-enable interrupts */ +#else + #define TICKLESS_DISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() /* this disables interrupts! Make sure they are re-enabled in vOnPreSleepProcessing()! */ + #define TICKLESS_ENABLE_INTERRUPTS() portENABLE_INTERRUPTS() /* re-enable interrupts */ +#endif + + #if 1 /* using ARM SysTick Timer */ + #if configSYSTICK_USE_LOW_POWER_TIMER + /* using Low Power Timer */ + #if CONFIG_PEX_SDK_USEDMCUC1_CONFIG_PEX_SDK_USED + #define LPTMR_CSR_TCF_MASK 0x80u + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR0_BASE_PTR->CSR&LPTMR_CSR_TCF_MASK)!=0/*! \todo */ /* returns TRUE if tick interrupt had fired */ + #else + #define TICK_INTERRUPT_HAS_FIRED() (LPTMR_PDD_GetInterruptFlag(LPTMR0_BASE_PTR)!=0) /* returns TRUE if tick interrupt had fired */ + #endif + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #else + /* using directly SysTick Timer */ + #define TICK_INTERRUPT_HAS_FIRED() ((portNVIC_SYSTICK_CTRL_REG&portNVIC_SYSTICK_COUNT_FLAG_BIT)!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() /* not needed */ + #define TICK_INTERRUPT_FLAG_SET() /* not needed */ + #endif + #else + /* using global variable to find out if interrupt has fired */ + volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ + #define TICK_INTERRUPT_HAS_FIRED() (portTickCntr!=0) /* returns TRUE if tick interrupt had fired */ + #define TICK_INTERRUPT_FLAG_RESET() portTickCntr=0 + #define TICK_INTERRUPT_FLAG_SET() portTickCntr=1 + #endif +#endif /* configUSE_TICKLESS_IDLE == 1 */ + +/* + * The maximum number of tick periods that can be suppressed is limited by the + * resolution of the tick timer. + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t xMaximumPossibleSuppressedTicks = 0; +#endif /* configUSE_TICKLESS_IDLE */ + +/* + * Compensate for the CPU cycles that pass while the tick timer is stopped (low + * power functionality only). + */ +#if configUSE_TICKLESS_IDLE == 1 + static TickCounter_t ulStoppedTimerCompensation = 0; /* number of timer ticks to compensate */ + #define configSTOPPED_TIMER_COMPENSATION 45UL /* number of CPU cycles to compensate. ulStoppedTimerCompensation will contain the number of timer ticks. */ +#endif /* configUSE_TICKLESS_IDLE */ + +/* Flag indicating that the tick counter interval needs to be restored back to + * the normal setting. Used when woken up from a low power mode using the LPTMR. + */ +#if configUSE_TICKLESS_IDLE && configSYSTICK_USE_LOW_POWER_TIMER + static uint8_t restoreTickInterval = 0; /* used to flag in tick ISR that compare register needs to be reloaded */ +#endif + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portINITIAL_FORMAT_VECTOR ((portSTACK_TYPE)0x4000) + #define portINITIAL_STATUS_REGISTER ((portSTACK_TYPE)0x2000) /* Supervisor mode set. */ +#endif + +#if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + +/* For strict compliance with the Cortex-M spec the task start address should +have bit-0 clear, as it is loaded into the PC on exit from an ISR. */ +#define portSTART_ADDRESS_MASK ( ( StackType_t ) 0xfffffffeUL ) + +/* Constants required to manipulate the core. + * SysTick register: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html + * Registers first... + */ +#define portNVIC_SYSTICK_CTRL_REG (*((volatile unsigned long *)0xe000e010)) /* SYST_CSR, SysTick Control and Status Register */ +#define portNVIC_SYSTICK_LOAD_REG (*((volatile unsigned long *)0xe000e014)) /* SYST_RVR, SysTick reload value register */ +#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile unsigned long *)0xe000e018)) /* SYST_CVR, SysTick current value register */ +#define portNVIC_SYSTICK_CALIB_VALUE_REG (*((volatile unsigned long *)0xe000e01C)) /* SYST_CALIB, SysTick calibration value register */ +/* ...then bits in the registers. */ +#define portNVIC_SYSTICK_COUNT_FLAG_BIT (1UL<<16UL) /* returns 1 if timer counted to 0 since the last read of the register */ +#if configSYSTICK_USE_CORE_CLOCK + #define portNVIC_SYSTICK_CLK_BIT (1UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#else + #define portNVIC_SYSTICK_CLK_BIT (0UL<<2UL) /* clock source. 1: core clock, 0: external reference clock */ +#endif +#define portNVIC_SYSTICK_INT_BIT (1UL<<1UL) /* SysTick interrupt enable bit */ +#define portNVIC_SYSTICK_ENABLE_BIT (1UL<<0UL) /* SysTick enable bit */ + +/* Constants required to manipulate the NVIC: */ +#define portNVIC_INT_CTRL ((volatile unsigned long*)0xe000ed04) /* interrupt control and state register (ICSR) */ +#define portNVIC_PENDSVSET_BIT (1UL<<28UL) /* bit 28 in portNVIC_INT_CTRL (PENDSVSET), see http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Cihfaaha.html */ +#define portNVIC_PENDSVCLEAR_BIT (1UL<<27UL) /* bit 27 in portNVIC_INT_CTRL (PENDSVCLR) */ +#define portNVIC_PEND_SYSTICK_SET_BIT (1UL<<26UL) /* bit 26 in portNVIC_INT_CTRL (PENDSTSET) */ +#define portNVIC_PEND_SYSTICK_CLEAR_BIT (1UL<<25UL) /* bit 25 in portNVIC_INT_CTRL (PENDSTCLR) */ + +#define portNVIC_SYSPRI2 ((volatile unsigned long*)0xe000ed1c) /* system handler priority register 2 (SHPR2), used for SVCall priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SVCALL_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SVCall interrupt (in portNVIC_SYSPRI2) */ + +#define portNVIC_SYSPRI3 ((volatile unsigned long*)0xe000ed20) /* system handler priority register 3 (SHPR3), used for SysTick and PendSV priority, http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CIAGECDD.html */ +#define portNVIC_SYSTICK_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<24) /* priority of SysTick interrupt (in portNVIC_SYSPRI3) */ +#define portNVIC_PENDSV_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<16) /* priority of PendableService interrupt (in portNVIC_SYSPRI3) */ + +#define portNVIC_SYSPRI7 ((volatile unsigned long*)0xe000e41c) /* system handler priority register 7, PRI_28 is LPTMR */ +#define portNVIC_LP_TIMER_PRI (((unsigned long)configKERNEL_INTERRUPT_PRIORITY)<<0) /* priority of low power timer interrupt */ + +#if configSYSTICK_USE_LOW_POWER_TIMER && MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT +#define IRQn_Type int +#define __NVIC_PRIO_BITS configPRIO_BITS +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; +#else /* M0+ */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; +#endif + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + +/** \brief Set Interrupt Priority + The function sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +static void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); /* set Priority for device specific Interrupts */ +#else /* M0+ */ + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); /* set Priority for device specific Interrupts */ +#endif +} + +/** \brief Enable External Interrupt + The function enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +static void NVIC_EnableIRQ(IRQn_Type IRQn) { + IRQn -= 16; /* PEx starts numbers with zero, while system interrupts would be negative */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +#else /* M0+ */ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */ +#endif +} +#endif /* configSYSTICK_USE_LOW_POWER_TIMER */ + +/* Constants required to set up the initial stack. */ +#define portINITIAL_XPSR (0x01000000) +#define portINITIAL_EXEC_RETURN (0xfffffffd) +#define portINITIAL_CONTROL_IF_UNPRIVILEGED (0x03) +#define portINITIAL_CONTROL_IF_PRIVILEGED (0x02) + +#if configENABLE_FPU + /* Constants required to manipulate the VFP. */ + #define portFPCCR ((volatile unsigned long *)0xe000ef34) /* Floating point context control register. */ + #define portASPEN_AND_LSPEN_BITS (0x3UL<<30UL) +#endif +#endif +/* Used to keep track of the number of nested calls to taskENTER_CRITICAL(). + This will be set to 0 prior to the first task being started. */ +/* Each task maintains its own interrupt status in the critical nesting variable. */ +static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa; + +#if INCLUDE_vTaskEndScheduler +#include +static jmp_buf xJumpBuf; /* Used to restore the original context when the scheduler is ended. */ +#endif +/*-----------------------------------------------------------*/ +void prvTaskExitError(void) { + /* A function that implements a task must not exit or attempt to return to + its caller as there is nothing to return to. If a task wants to exit it + should instead call vTaskDelete( NULL ). + + Artificially force an assert() to be triggered if configASSERT() is + defined, then stop here so application writers can catch the error. */ + configASSERT(uxCriticalNesting == ~0UL); + portDISABLE_INTERRUPTS(); + for(;;) { + /* wait here */ + } +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY)) /* ARM M4(F)/M7/M33 core */ +__asm uint32_t ulPortSetInterruptMask(void) { + PRESERVE8 + + mrs r0, basepri + mov r1, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r1 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) && (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) +__asm void vPortClearInterruptMask(uint32_t ulNewMask) { + PRESERVE8 + + msr basepri, r0 + bx r14 +} +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if configENABLE_MPU +StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged) { +#else +StackType_t *pxPortInitialiseStack(portSTACK_TYPE *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters) { +#endif + /* Simulate the stack frame as it would be created by a context switch interrupt. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts, and to ensure alignment. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR */ + pxTopOfStack--; +#if configENABLE_MPU + *pxTopOfStack = ((StackType_t)pxCode)&portSTART_ADDRESS_MASK; /* PC */ +#else + *pxTopOfStack = ((StackType_t)pxCode); /* PC */ +#endif + pxTopOfStack--; + *pxTopOfStack = (StackType_t)portTASK_RETURN_ADDRESS; /* LR */ + + /* Save code space by skipping register initialization. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = (portSTACK_TYPE)pvParameters; /* R0 */ + +#if configENABLE_FPU /* has floating point unit */ + /* A save method is being used that requires each task to maintain its + own exec return value. */ + pxTopOfStack--; + *pxTopOfStack = portINITIAL_EXEC_RETURN; +#endif +#if configENABLE_MPU + pxTopOfStack -= 9; /* R11, R10, R9, R8, R7, R6, R5 and R4 plus privilege level */ + if (xRunPrivileged == pdTRUE) { + *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED; + } else { + *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED; + } +#else + pxTopOfStack -= 8; /* R11, R10, R9, R8, R7, R6, R5 and R4. */ +#endif + return pxTopOfStack; +} + +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_S08_FSL) || (configCOMPILER==configCOMPILER_S12_FSL) +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma MESSAGE DISABLE C20000 /* dead code detected */ + #pragma NO_RETURN + #pragma CODE_SEG __NEAR_SEG NON_BANKED +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DISABLE C1404 /* return expected */ + #pragma NO_RETURN +#endif + +static portBASE_TYPE xBankedStartScheduler(void) { + /* Restore the context of the first task. */ + portRESTORE_CONTEXT(); /* Simulate the end of an interrupt to start the scheduler off. */ + /* Should not get here! */ + return pdFALSE; +} + +#if (configCOMPILER==configCOMPILER_S08_FSL) + #pragma CODE_SEG DEFAULT + #pragma MESSAGE DEFAULT C1404 /* return expected */ + #pragma MESSAGE DEFAULT C20000 /* dead code detected */ +#elif (configCOMPILER==configCOMPILER_S12_FSL) + #pragma MESSAGE DEFAULT C1404 /* return expected */ +#endif +#endif +/*-----------------------------------------------------------*/ +#if configUSE_TICKLESS_IDLE == 1 +void FRTOS1_vOnPreSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +void FRTOS1_vOnPostSleepProcessing(TickType_t expectedIdleTicks); /* prototype */ + +#if (configCOMPILER==configCOMPILER_ARM_GCC) || (configCOMPILER==configCOMPILER_ARM_KEIL) +__attribute__((weak)) +#endif +void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { + unsigned long ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickIncrements; + TickCounter_t tmp; /* because of how we get the current tick counter */ + bool tickISRfired; + uint32_t tickDuration; + +#if configSYSTICK_USE_LOW_POWER_TIMER + /* if we wait for the tick interrupt, do not enter low power again below */ + if (restoreTickInterval!=0) { + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* default example code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + return; + } +#endif + + /* Make sure the tick timer reload value does not overflow the counter. */ + if(xExpectedIdleTime > xMaximumPossibleSuppressedTicks) { + xExpectedIdleTime = xMaximumPossibleSuppressedTicks; + } + + /* Stop the tick timer momentarily. The time the counter is stopped for + * is accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else /* using normal timer or SysTick */ + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + /* Calculate the reload value required to wait xExpectedIdleTime + * tick periods. This code will execute part way through one + * of the tick periods. + */ + /* -1UL is used because this code will execute part way through one of the tick periods */ +#if COUNTS_UP + ulReloadValue = (UL_TIMER_COUNTS_FOR_ONE_TICK*xExpectedIdleTime); + #if configSYSTICK_USE_LOW_POWER_TIMER + if (ulReloadValue > 0) { /* make sure it does not underflow */ + ulReloadValue -= 1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + } + #endif + if (tmp!=0 && ulReloadValue>=tmp) { /* make sure it does not underflow */ + ulReloadValue -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + ulReloadValue = tmp+(UL_TIMER_COUNTS_FOR_ONE_TICK*(xExpectedIdleTime-1UL)); +#endif + if (ulStoppedTimerCompensation!=0 && ulReloadValue>ulStoppedTimerCompensation) { + ulReloadValue -= ulStoppedTimerCompensation; + } + + /* Enter a critical section but don't use the taskENTER_CRITICAL() + * method as that will mask interrupts that should exit sleep mode. + */ + TICKLESS_DISABLE_INTERRUPTS(); + + /* If a context switch is pending or a task is waiting for the scheduler + * to be unsuspended then abandon the low power entry. + */ + if (eTaskConfirmSleepModeStatus()==eAbortSleep) { + /* Must restore the duration before re-enabling the timers */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK-1UL; /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tmp!=0 && tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; /* take into account what we already executed in the current tick period */ + } +#else + tickDuration = tmp; +#endif + SET_TICK_DURATION(tickDuration); + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICKLESS_ENABLE_INTERRUPTS(); + } else { + SET_TICK_DURATION(ulReloadValue); /* Set the new reload value. */ + RESET_TICK_COUNTER_VAL(); /* Reset the counter. */ + ENABLE_TICK_COUNTER(); /* Restart tick timer. */ + TICK_INTERRUPT_FLAG_RESET(); /* reset flag so we know later if it has fired */ + + /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can + * set its parameter to 0 to indicate that its implementation contains + * its own wait for interrupt or wait for event instruction, and so wfi + * should not be executed again. However, the original expected idle + * time variable must remain unmodified, so a copy is taken. + */ + + /* CPU *HAS TO WAIT* in the sequence below for an interrupt. If vOnPreSleepProcessing() is not used, a default implementation is provided */ + FRTOS1_vOnPreSleepProcessing(xExpectedIdleTime); /* go into low power mode. Re-enable interrupts as needed! */ +#if 0 /* example/default code */ + /* default wait/sleep code */ + __asm volatile("dsb"); + __asm volatile("wfi"); + __asm volatile("isb"); +#endif + /* ---------------------------------------------------------------------------- + * Here the CPU *HAS TO BE* low power mode, waiting to wake up by an interrupt + * ----------------------------------------------------------------------------*/ + FRTOS1_vOnPostSleepProcessing(xExpectedIdleTime); /* process post-low power actions */ + /* Stop tick counter. Again, the time the tick counter is stopped for is + * accounted for as best it can be, but using the tickless mode will + * inevitably result in some tiny drift of the time maintained by the + * kernel with respect to calendar time. + */ + tickISRfired = (bool)TICK_INTERRUPT_HAS_FIRED(); /* need to check Interrupt flag here, as might be modified below */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* disabling the LPTMR does reset the timer register! So I need to get the value first, then disable the timer: */ + GET_TICK_CURRENT_VAL(&tmp); + DISABLE_TICK_COUNTER(); +#else + DISABLE_TICK_COUNTER(); + GET_TICK_CURRENT_VAL(&tmp); +#endif + TICKLESS_ENABLE_INTERRUPTS();/* Re-enable interrupts */ + if (tickISRfired) { + /* The tick interrupt has already executed, and the timer + * count reloaded with the modulo/match value. + * Reset the counter register with whatever remains of + * this tick period. + */ +#if COUNTS_UP + #if configSYSTICK_USE_LOW_POWER_TIMER + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); /* LPTMR: interrupt will happen at match of compare register && increment, thus minus 1 */ + #else + tickDuration = UL_TIMER_COUNTS_FOR_ONE_TICK; + #endif + if (tickDuration >= tmp) { /* make sure it does not underflow */ + tickDuration -= tmp; + } + if (tickDuration > 1) { + /*! \todo Need to rethink this one! */ + //tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + vTaskStepTick(1); + } +#else + tickDuration = (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)-(ulReloadValue-tmp); +#endif + SET_TICK_DURATION(tickDuration); + /* The tick interrupt handler will already have pended the tick + * processing in the kernel. As the pending tick will be + * processed as soon as this function exits, the tick value + * maintained by the tick is stepped forward by one less than the + * time spent waiting. + */ + ulCompleteTickPeriods = xExpectedIdleTime-1UL; /* -1 because we already added a completed tick from the tick interrupt */ + } else { + /* Something other than the tick interrupt ended the sleep. + * Work out how long the sleep lasted rounded to complete tick + * periods (not the ulReload value which accounted for part ticks). + */ +#if COUNTS_UP + ulCompletedSysTickIncrements = tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = (((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-1)-ulCompletedSysTickIncrements; + if (tickDuration > 1) { + tickDuration -= 1; /* decrement by one, to compensate for one timer tick, as we are already part way through it */ + } else { + /* Not enough time to setup for the next tick, so skip it and setup for the + * next. Make sure to count the tick we skipped. + */ + tickDuration += (UL_TIMER_COUNTS_FOR_ONE_TICK - 1UL); + if (tickDuration > 1) { /* check for underflow */ + tickDuration -= 1; + } + vTaskStepTick(1); + } +#else + ulCompletedSysTickIncrements = (xExpectedIdleTime*UL_TIMER_COUNTS_FOR_ONE_TICK)-tmp; + /* How many complete tick periods passed while the processor was waiting? */ + ulCompleteTickPeriods = ulCompletedSysTickIncrements/UL_TIMER_COUNTS_FOR_ONE_TICK; + /* The reload value is set to whatever fraction of a single tick period remains. */ + tickDuration = ((ulCompleteTickPeriods+1)*UL_TIMER_COUNTS_FOR_ONE_TICK)-ulCompletedSysTickIncrements; +#endif + SET_TICK_DURATION(tickDuration); + } + /* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG + again, then set portNVIC_SYSTICK_LOAD_REG back to its standard + value. The critical section is used to ensure the tick interrupt + can only execute once in the case that the reload register is near + zero. + */ + RESET_TICK_COUNTER_VAL(); + portENTER_CRITICAL(); + { + ENABLE_TICK_COUNTER(); + if (ulCompleteTickPeriods>0) { + vTaskStepTick(ulCompleteTickPeriods); + } +#if configSYSTICK_USE_LOW_POWER_TIMER + /* The compare register of the LPTMR should not be modified when the + * timer is running, so wait for the next tick interrupt to change it. + */ + if (tickDuration != (UL_TIMER_COUNTS_FOR_ONE_TICK-1UL)) { /* minus one because of LPTMR way to trigger interrupts */ + if (tickISRfired) { + /* The pending tick interrupt will be immediately processed after + * exiting this function so we need to delay the change of the tick + * duration until the one after that. + */ + restoreTickInterval = 2; + } else { + /* Notify the tick interrupt that the tick duration needs to be + * changed back to the normal setting. + */ + restoreTickInterval = 1; + } + } else { + /* If the duration is the standard full tick, then there's no reason + * to stop and restart LPTMR in the tick interrupt. + */ + restoreTickInterval = 0; + } +#else + /* The systick has a load register that will automatically be used + * when the counter counts down to zero. + */ + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); +#endif + } + portEXIT_CRITICAL(); + } +} +#endif /* #if configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ +static void vPortInitTickTimer(void) { +#if configUSE_TICKLESS_IDLE == 1 +{ +#if TICK_NOF_BITS==32 + xMaximumPossibleSuppressedTicks = 0xffffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 32bit timer register */ +#elif TICK_NOF_BITS==24 + xMaximumPossibleSuppressedTicks = 0xffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 24bit timer register */ +#elif TICK_NOF_BITS==16 + xMaximumPossibleSuppressedTicks = 0xffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 16bit timer register */ +#elif TICK_NOF_BITS==8 + xMaximumPossibleSuppressedTicks = 0xffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 8bit timer register */ +#else + error "unknown configuration!" +#endif +#if configSYSTICK_USE_LOW_POWER_TIMER + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ); +#else + ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_CLOCK_HZ); +#endif +} +#endif /* configUSE_TICKLESS_IDLE */ +#if configSYSTICK_USE_LOW_POWER_TIMER + /* SIM_SCGx: enable clock to LPTMR */ +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + SIM_PDD_SetClockGate(SIM_BASE_PTR, SIM_PDD_CLOCK_GATE_LPTMR0, PDD_ENABLE); + + /* LPTRM0_CSR: clear TCF (Timer compare Flag) with writing a one to it */ + LPTMR_PDD_ClearInterruptFlag(LPTMR0_BASE_PTR); + + /* LPTMR_PSR: configure prescaler, bypass and clock source */ + /* PBYP PCS + * ERCLK32 1 10 + * LPO_1kHz 1 01 + * ERCLK 0 00 + * IRCLK 1 00 + */ + LPTMR_PDD_SelectPrescalerSource(LPTMR0_BASE_PTR, LPTMR_PDD_SOURCE_LPO1KHZ); + LPTMR_PDD_EnablePrescalerBypass(LPTMR0_BASE_PTR, LPTMR_PDD_BYPASS_ENABLED); +#elif MCUC1_CONFIG_NXP_SDK_2_0_USED + /*! \todo */ + { + lptmr_config_t config; + + LPTMR_GetDefaultConfig(&config); + LPTMR_Init(LPTMR0_BASE_PTR, &config); + } +#endif + /* set timer interrupt priority in IP[] and enable it in ISER[] */ + NVIC_SetPriority(configLOW_POWER_TIMER_VECTOR_NUMBER, configLIBRARY_LOWEST_INTERRUPT_PRIORITY); + NVIC_EnableIRQ(configLOW_POWER_TIMER_VECTOR_NUMBER); /* enable IRQ in NVIC_ISER[] */ +#else /* use normal SysTick Counter */ + *(portNVIC_SYSPRI3) |= portNVIC_SYSTICK_PRI; /* set priority of SysTick interrupt */ +#endif + /* Configure timer to interrupt at the requested rate. */ + DISABLE_TICK_COUNTER(); /* disable the timer, just in case it is already running */ + SET_TICK_DURATION(TIMER_COUNTS_FOR_ONE_TICK-1UL); /* set tick period */ + RESET_TICK_COUNTER_VAL(); /* reset counter so it starts properly */ + ENABLE_TICK_COUNTER(); /* let it run */ +} +/*-----------------------------------------------------------*/ +static void vPortStartTickTimer(void) { + ENABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +void vPortStopTickTimer(void) { + DISABLE_TICK_COUNTER(); +} +/*-----------------------------------------------------------*/ +#if configENABLE_FPU /* has floating point unit */ +void vPortEnableVFP(void) { +#if 1 /* configLTO_HELPER: using implementation in C which is portable */ + #define CPACR_REG_MEM ((volatile int*)0xE000ED88) /* location of the CPACR register */ + + *CPACR_REG_MEM |= (0xf<<20); /* Enable CP10 and CP11 coprocessors */ +#else /* below is the original assembly code which fails with -flto because of the constant load */ + __asm volatile + ( + " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ + " ldr r1, [r0] \n" + " orr r1, r1, #( 0xf << 20 ) \n" /* Enable CP10 and CP11 coprocessors, then save back. */ + " str r1, [r0] \n" + " bx r14 " + ); +#endif +} +#endif /* M4/M7 */ +/*-----------------------------------------------------------*/ +/* + * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure + * FreeRTOS API functions are not called from interrupts that have been assigned + * a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY. + */ +#if (configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */) && (configASSERT_DEFINED == 1) + /* Constants required to check the validity of an interrupt priority. */ + #define portFIRST_USER_INTERRUPT_NUMBER ( 16 ) + #define portNVIC_IP_REGISTERS_OFFSET_16 ( 0xE000E3F0 ) + #define portAIRCR_REG ( * ( ( volatile uint32_t * ) 0xE000ED0C ) ) + #define portMAX_8_BIT_VALUE ( ( uint8_t ) 0xff ) + #define portTOP_BIT_OF_BYTE ( ( uint8_t ) 0x80 ) + #define portMAX_PRIGROUP_BITS ( ( uint8_t ) 7 ) + #define portPRIORITY_GROUP_MASK ( 0x07UL << 8UL ) + #define portPRIGROUP_SHIFT ( 8UL ) + + static uint8_t ucMaxSysCallPriority = 0; + static uint32_t ulMaxPRIGROUPValue = 0; + static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16; +#endif /* configASSERT_DEFINED */ + +BaseType_t xPortStartScheduler(void) { + /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0. + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ + configASSERT( configMAX_SYSCALL_INTERRUPT_PRIORITY ); + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t ulOriginalPriority; + volatile uint8_t * const pucFirstUserPriorityRegister = ( volatile uint8_t * const ) ( portNVIC_IP_REGISTERS_OFFSET_16 + portFIRST_USER_INTERRUPT_NUMBER ); + volatile uint8_t ucMaxPriorityValue; + + /* Determine the maximum priority from which ISR safe FreeRTOS API + functions can be called. ISR safe functions are those that end in + "FromISR". FreeRTOS maintains separate thread and ISR API functions to + ensure interrupt entry is as fast and simple as possible. + + Save the interrupt priority value that is about to be clobbered. */ + ulOriginalPriority = *pucFirstUserPriorityRegister; + + /* Determine the number of priority bits available. First write to all + possible bits. */ + *pucFirstUserPriorityRegister = portMAX_8_BIT_VALUE; + + /* Read the value back to see how many bits stuck. */ + ucMaxPriorityValue = *pucFirstUserPriorityRegister; + + /* Use the same mask on the maximum system call priority. */ + ucMaxSysCallPriority = configMAX_SYSCALL_INTERRUPT_PRIORITY & ucMaxPriorityValue; + + /* Calculate the maximum acceptable priority group value for the number + of bits read back. */ + ulMaxPRIGROUPValue = portMAX_PRIGROUP_BITS; + while( ( ucMaxPriorityValue & portTOP_BIT_OF_BYTE ) == portTOP_BIT_OF_BYTE ) + { + ulMaxPRIGROUPValue--; + ucMaxPriorityValue <<= ( uint8_t ) 0x01; + } + + /* Shift the priority group value back to its position within the AIRCR + register. */ + ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT; + ulMaxPRIGROUPValue &= portPRIORITY_GROUP_MASK; + + /* Restore the clobbered interrupt priority register to its original + value. */ + *pucFirstUserPriorityRegister = ulOriginalPriority; + } + #endif /* conifgASSERT_DEFINED */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) */ /* ARM M4(F)/M7 core */ + +#if configCPU_FAMILY==configCPU_FAMILY_ARM_M7F + /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7 r0p1 port. */ + #define portCPUID (*((volatile uint32_t*)0xE000ed00)) + #define portCORTEX_M7_r0p0_ID (0x410FC270UL) + #define portCORTEX_M7_r0p1_ID (0x410FC271UL) /* this one will require a special port! Writing to the BASEPRIO is not taking effect immediately, even with memory barrier instructions. Workaround: globally disable interrupts before writing to BASEPRIO, then write, then use memory barrier. */ + #define portCORTEX_M7_r0p2_ID (0x410FC272UL) /* is present on the TWR-KV57F220M */ + + configASSERT(portCPUID!=portCORTEX_M7_r0p1_ID); /* this one will require a special port! */ +#endif + + /* Make PendSV, SVCall and SysTick the lowest priority interrupts. SysTick priority will be set in vPortInitTickTimer(). */ +#if 0 /* do NOT set the SVCall priority */ + /* why: execution of an SVC instruction at a priority equal or higher than SVCall can cause a hard fault (at least on Cortex-M4), + see https://community.freescale.com/thread/302511 */ + *(portNVIC_SYSPRI2) |= portNVIC_SVCALL_PRI; /* set priority of SVCall interrupt */ +#endif + *(portNVIC_SYSPRI3) |= portNVIC_PENDSV_PRI; /* set priority of PendSV interrupt */ + uxCriticalNesting = 0; /* Initialize the critical nesting count ready for the first task. */ + vPortInitTickTimer(); /* initialize tick timer */ + vPortStartTickTimer(); /* start tick timer */ +#if configENABLE_FPU /* has floating point unit */ + vPortEnableVFP(); /* Ensure the VFP is enabled - it should be anyway */ + *(portFPCCR) |= portASPEN_AND_LSPEN_BITS; /* Lazy register save always */ +#endif +#if INCLUDE_vTaskEndScheduler + if(setjmp(xJumpBuf) != 0 ) { + /* here we will get in case of a call to vTaskEndScheduler() */ + __asm volatile( + " movs r0, #0 \n" /* Reset CONTROL register and switch back to the MSP stack. */ + " msr CONTROL, r0 \n" + " dsb \n" + " isb \n" + ); + return pdFALSE; + } +#endif + vPortStartFirstTask(); /* Start the first task. */ + /* Should not get here! */ + return pdFALSE; +} +/*-----------------------------------------------------------*/ +void vPortEndScheduler(void) { + vPortStopTickTimer(); + vPortInitializeHeap(); + uxCriticalNesting = 0xaaaaaaaa; + /* Jump back to the processor state prior to starting the + scheduler. This means we are not going to be using a + task stack frame so the task can be deleted. */ +#if INCLUDE_vTaskEndScheduler + longjmp(xJumpBuf, 1); +#else + for(;;){} /* wait here */ +#endif +} +/*-----------------------------------------------------------*/ +void vPortEnterCritical(void) { +/* + * Disable interrupts before incrementing the count of critical section nesting. + * The nesting count is maintained so we know when interrupts should be + * re-enabled. Once interrupts are disabled the nesting count can be accessed + * directly. Each task maintains its own nesting count. + */ + portDISABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + uxCriticalNesting++; +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* This is not the interrupt safe version of the enter critical function so + assert() if it is being called from an interrupt context. Only API + functions that end in "FromISR" can be used in an interrupt. Only assert if + the critical nesting count is 1 to protect against recursive calls if the + assert function also uses a critical section. */ + if( uxCriticalNesting == 1 ) + { + /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */ + #define portVECTACTIVE_MASK (0xFFUL) + + configASSERT(((*portNVIC_INT_CTRL) & portVECTACTIVE_MASK)==0); + } +#endif + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +void vPortExitCritical(void) { + /* Interrupts are disabled so we can access the nesting count directly. If the + * nesting is found to be 0 (no nesting) then we are leaving the critical + * section and interrupts can be re-enabled. + */ + uxCriticalNesting--; + if (uxCriticalNesting == 0) { + portENABLE_INTERRUPTS(); + portPOST_ENABLE_DISABLE_INTERRUPTS(); + } +} +/*-----------------------------------------------------------*/ +void vPortYieldFromISR(void) { + /* Set a PendSV to request a context switch. */ + *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET_BIT; + /* Barriers are normally not required but do ensure the code is completely + within the specified behavior for the architecture. */ + __asm volatile("dsb"); + __asm volatile("isb"); +} +/*-----------------------------------------------------------*/ +/* return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time */ + uint32_t uxGetTickCounterValue(void) { + long val; + + GET_TICK_CURRENT_VAL(&val); + return val; +} +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + /* this is how we get here: + RTOSTICKLDD1_Interrupt: + push {r4, lr} + ... RTOSTICKLDD1_OnCounterRestart + bl RTOSTICKLDD1_OnCounterRestart -> push {r4,lr} + pop {r4, lr} mov r4,r0 + bl vPortTickHandler + pop {r4,pc} + */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + portDISABLE_INTERRUPTS(); /* disable interrupts */ +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + taskYIELD(); + } + portENABLE_INTERRUPTS(); /* enable interrupts again */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +#if configSYSTICK_USE_LOW_POWER_TIMER +void LPTMR0_IRQHandler(void) { /* low power timer */ +#else +void SysTick_Handler(void) { /* normal SysTick */ +#endif +#else +void vPortTickHandler(void) { +#endif + ACKNOWLEDGE_TICK_ISR(); +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS && configCPU_FAMILY==configCPU_FAMILY_ARM_M0P + SEGGER_SYSVIEW_TickCnt++; /* tick counter for Segger SystemViewer */ +#endif +#if configUSE_TICKLESS_IDLE == 1 + TICK_INTERRUPT_FLAG_SET(); +#endif + /* The SysTick runs at the lowest interrupt priority, so when this interrupt + executes all interrupts must be unmasked. There is therefore no need to + save and then restore the interrupt mask value as its value is already + known. */ + portDISABLE_INTERRUPTS(); /* disable interrupts */ + traceISR_ENTER(); +#if (configUSE_TICKLESS_IDLE == 1) && configSYSTICK_USE_LOW_POWER_TIMER + if (restoreTickInterval > 0) { /* we got interrupted during tickless mode and non-standard compare value: reload normal compare value */ + if (restoreTickInterval == 1) { + DISABLE_TICK_COUNTER(); + SET_TICK_DURATION(UL_TIMER_COUNTS_FOR_ONE_TICK-1UL); + ENABLE_TICK_COUNTER(); + } + restoreTickInterval -= 1; + } +#endif + if (xTaskIncrementTick()!=pdFALSE) { /* increment tick count */ + traceISR_EXIT_TO_SCHEDULER(); + taskYIELD(); + } else { + traceISR_EXIT(); + } + portENABLE_INTERRUPTS(); /* re-enable interrupts */ +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_DSC_FSL) +void vPortStartFirstTask(void) { + /* Restore the context of the first task to run. */ + portRESTORE_CONTEXT(); + /* Simulate the end of the yield function. */ + __asm(rts); +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +__asm void vPortStartFirstTask(void) { +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + /* Use the NVIC offset register to locate the stack. */ +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler + ldr r0, =0xE000ED08 + ldr r0, [r0] + ldr r0, [r0] + /* Set the msp back to the start of the stack. */ + msr msp, r0 +#endif + /* Globally enable interrupts. */ + cpsie i + /* Call SVC to start the first task. */ + svc 0 + nop + nop + nop +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + extern pxCurrentTCB; + + PRESERVE8 + + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + + ldr r3, =pxCurrentTCB /* Obtain location of pxCurrentTCB. */ + ldr r1, [r3] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #32 /* Discard everything up to r0. */ + msr psp, r0 /* This is now the new top of stack to use in the task. */ + movs r0, #2 /* Switch to the psp stack. */ + msr CONTROL, r0 + isb + pop {r0-r5} /* Pop the registers that are saved automatically. */ + mov lr, r5 /* lr is now in r5. */ + pop {r3} /* The return address is now in r3. */ + pop {r2} /* Pop and discard the XPSR. */ + cpsie i /* The first task has its context and interrupts can be enabled. */ + bx r3 /* Finally, jump to the user defined task code. */ + + ALIGN +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +/* Need the 'noinline', as latest gcc with -O3 tries to inline it, and gives error message: "Error: symbol `pxCurrentTCBConst2' is already defined" */ +__attribute__((noinline)) +void vPortStartFirstTask(void) { +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* only needed for openOCD or Segger FreeRTOS thread awareness. It needs the symbol uxTopUsedPriority present after linking */ + { + extern volatile const int uxTopUsedPriority; + __attribute__((__unused__)) volatile uint8_t dummy_value_for_openocd; + dummy_value_for_openocd = uxTopUsedPriority; + } +#endif +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) + /* reference FreeRTOSDebugConfig, otherwise it might get removed by the linker or optimizations */ + { + extern const uint8_t FreeRTOSDebugConfig[]; + if (FreeRTOSDebugConfig[0]==0) { /* just use it, so the linker cannot remove FreeRTOSDebugConfig[] */ + for(;;); /* FreeRTOSDebugConfig[0] should always be non-zero, so this should never happen! */ + } + } +#endif +#if configHEAP_SCHEME_IDENTIFICATION + extern const uint8_t freeRTOSMemoryScheme; /* constant for NXP Kernel Awareness to indicate heap scheme */ + if (freeRTOSMemoryScheme>100) { /* reference/use variable so it does not get optimized by the linker */ + for(;;); + } +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configRESET_MSP && !INCLUDE_vTaskEndScheduler +#if configLTO_HELPER /* with -flto, we cannot load the constant directly, otherwise we get "Error: offset out of range" with "lto-wrapper failed" */ + " mov r0, #0xE0000000 \n" /* build the constant 0xE000ED08. First load the upper 16 bits */ + " mov r1, #0xED00 \n" /* next load part of the lower 16 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED00 in R0 */ + " mov r1, #0x08 \n" /* next load the lowest 8 bit */ + " orr r0, r1 \n" /* and or it into R0. Now we have 0xE000ED08 in R0 */ +#else + " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ +#endif + " ldr r0, [r0] \n" /* load address of vector table */ + " ldr r0, [r0] \n" /* load first entry of vector table which is the reset stack pointer */ + " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ +#endif + " cpsie i \n" /* Globally enable interrupts. */ + " svc 0 \n" /* System call to start first task. */ + " nop \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* With the latest FreeRTOS, the port for M0+ does not use the SVC instruction + * and does not need vPortSVCHandler() any more. + */ + /* The MSP stack is not reset as, unlike on M3/4 parts, there is no vector + table offset register that can be used to locate the initial stack value. + Not all M0 parts have the application vector table at address 0. */ + __asm volatile( + " ldr r2, pxCurrentTCBConst2 \n" /* Obtain location of pxCurrentTCB. */ + " ldr r3, [r2] \n" + " ldr r0, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, #32 \n" /* Discard everything up to r0. */ + " msr psp, r0 \n" /* This is now the new top of stack to use in the task. */ + " movs r0, #2 \n" /* Switch to the psp stack. */ + " msr CONTROL, r0 \n" + " isb \n" + " pop {r0-r5} \n" /* Pop the registers that are saved automatically. */ + " mov lr, r5 \n" /* lr is now in r5. */ + " pop {r3} \n" /* Return address is now in r3. */ + " pop {r2} \n" /* Pop and discard XPSR. */ + " cpsie i \n" /* The first task has its context and interrupts can be enabled. */ + " bx r3 \n" /* Finally, jump to the user defined task code. */ + " \n" + " .align 4 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB" + ); +#endif +} +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + + /* Get the location of the current TCB. */ + ldr r3, =pxCurrentTCB + ldr r1, [r3] + ldr r0, [r1] + /* Pop the core registers. */ +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* \todo: r14, check http://sourceforge.net/p/freertos/discussion/382005/thread/a9406af1/?limit=25#3bc7 */ +#else + ldmia r0!, {r4-r11} +#endif + msr psp, r0 + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 +#if configENABLE_FPU +#else + orr r14, r14, #13 +#endif + bx r14 +} +/*-----------------------------------------------------------*/ +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ and Keil */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void SVC_Handler(void) { +#else +__asm void vPortSVCHandler(void) { +#endif + /* This function is no longer used, but retained for backward + compatibility. */ +} +#endif +#endif +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void SVC_Handler(void) { +#else +__attribute__ ((naked)) void vPortSVCHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +__asm volatile ( + " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ + " ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */ + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + /* pop the core registers */ +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" +#else + " ldmia r0!, {r4-r11} \n" +#endif + " msr psp, r0 \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" +#if configENABLE_FPU +#else + " orr r14, r14, #13 \n" +#endif + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst2: .word pxCurrentTCB \n" + ); +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex M0+ */ + /* This function is no longer used, but retained for backward + compatibility. */ +#endif +} +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_KEIL) +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + PRESERVE8 + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] +#if configENABLE_FPU + tst r14, #0x10 /* Is the task using the FPU context? If so, push high vfp registers. */ + it eq + vstmdbeq r0!, {s16-s31} + + stmdb r0!, {r4-r11, r14} /* save remaining core registers */ +#else + stmdb r0!, {r4-r11} /* Save the core registers. */ +#endif + str r0, [r2] /* Save the new top of stack into the first member of the TCB. */ + stmdb sp!, {r3, r14} + mov r0, #configMAX_SYSCALL_INTERRUPT_PRIORITY + msr basepri, r0 + bl vTaskSwitchContext + mov r0, #0 + msr basepri, r0 + ldmia sp!, {r3, r14} + ldr r1, [r3] /* The first item in pxCurrentTCB is the task top of stack. */ + ldr r0, [r1] +#if configENABLE_FPU + ldmia r0!, {r4-r11, r14} /* Pop the core registers */ + tst r14, #0x10 /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + it eq + vldmiaeq r0!, {s16-s31} +#else + ldmia r0!, {r4-r11} /* Pop the core registers. */ +#endif + msr psp, r0 + bx r14 + nop +} +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Keil: Cortex M0+ */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__asm void PendSV_Handler(void) { +#else +__asm void vPortPendSVHandler(void) { +#endif + EXTERN pxCurrentTCB + EXTERN vTaskSwitchContext + + mrs r0, psp + + ldr r3, =pxCurrentTCB /* Get the location of the current TCB. */ + ldr r2, [r3] + + subs r0, #32 /* Make space for the remaining low registers. */ + str r0, [r2] /* Save the new top of stack. */ + stmia r0!, {r4-r7} /* Store the low registers that are not saved automatically. */ + mov r4, r8 /* Store the high registers. */ + mov r5, r9 + mov r6, r10 + mov r7, r11 + stmia r0!, {r4-r7} + + push {r3, r14} + cpsid i + bl vTaskSwitchContext + cpsie i + pop {r2, r3} /* lr goes in r3. r2 now holds tcb pointer. */ + + ldr r1, [r2] + ldr r0, [r1] /* The first item in pxCurrentTCB is the task top of stack. */ + adds r0, #16 /* Move to the high registers. */ + ldmia r0!, {r4-r7} /* Pop the high registers. */ + mov r8, r4 + mov r9, r5 + mov r10, r6 + mov r11, r7 + + msr psp, r0 /* Remember the new top of stack for the task. */ + + subs r0, #32 /* Go back for the low registers that are not automatically restored. */ + ldmia r0!, {r4-r7} /* Pop low registers. */ + + bx r3 + nop +} +#endif +#endif /* (configCOMPILER==configCOMPILER_ARM_KEIL) */ +/*-----------------------------------------------------------*/ +#if (configCOMPILER==configCOMPILER_ARM_GCC) +#if configGDB_HELPER +/* prototypes to avoid compiler warnings */ +__attribute__ ((naked)) void vPortPendSVHandler_native(void); +__attribute__ ((naked)) void PendSV_Handler_jumper(void); + +__attribute__ ((naked)) void vPortPendSVHandler_native(void) { +#elif !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB \n" + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConst: .word pxCurrentTCB" + ); +#endif +} + +#if configUSE_TOP_USED_PRIORITY || configLTO_HELPER + /* This is only really needed for debugging with openOCD: + * Since at least FreeRTOS V7.5.3 uxTopUsedPriority is no longer + * present in the kernel, so it has to be supplied by other means for + * OpenOCD's threads awareness. + * + * Add this file to your project, and, if you're using --gc-sections, + * ``--undefined=uxTopUsedPriority'' (or + * ``-Wl,--undefined=uxTopUsedPriority'' when using gcc for final + * linking) to your LDFLAGS; same with all the other symbols you need. + */ + volatile const int + #ifdef __GNUC__ + __attribute__((used)) + #endif + uxTopUsedPriority = configMAX_PRIORITIES-1; +#endif + +#if configGDB_HELPER /* if GDB debug helper is enabled */ +/* Credits to: + * - Artem Pisarneko for his initial contribution + * - Prasana for the PendSVHandler updates + * - Geoffrey Wossum for the Cortex-M4 contribution + */ + +/* Switch control variable: + * 0 - no hook installed (normal execution), + * 1 - hook installation performed, + * 2 - following hooked switches + */ +int volatile dbgPendSVHookState = 0; +/* Requested target task handle variable */ +void *volatile dbgPendingTaskHandle; + +const int volatile dbgFreeRTOSConfig_suspend_value = INCLUDE_vTaskSuspend; +const int volatile dbgFreeRTOSConfig_delete_value = INCLUDE_vTaskDelete; + +__attribute__ ((naked)) void PendSV_Handler_jumper(void) { + __asm volatile("b vPortPendSVHandler_native \n"); +} + +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ +__attribute__ ((naked)) void PendSV_Handler(void) { +#else +__attribute__ ((naked)) void vPortPendSVHandler(void) { +#endif +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + __asm volatile ( +#if configGDB_HELPER + " ldr r1, _dbgPendSVHookState \n" /* Check hook installed */ + " ldr r0, [r1] \n" + " cmp r0, #0 \n" + " beq PendSV_Handler_jumper \n" /* if no hook installed then jump to native handler, else proceed... */ + " cmp r0, #1 \n" /* check whether hook triggered for the first time... */ + " bne dbg_switch_to_pending_task \n" /* if not so, then jump to switching right now, otherwise current task context must be saved first... */ + " mov r0, #2 \n" /* mark hook after triggered for the first time */ + " str r0, [r1] \n" +#endif /* configGDB_HELPER */ + " mrs r0, psp \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" +#if configENABLE_FPU + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push high vfp registers. */ + " it eq \n" + " vstmdbeq r0!, {s16-s31} \n" + + " stmdb r0!, {r4-r11, r14} \n" /* save remaining core registers */ +#else + " stmdb r0!, {r4-r11} \n" /* Save the core registers. */ +#endif + " str r0, [r2] \n" /* Save the new top of stack into the first member of the TCB. */ + " stmdb sp!, {r3, r14} \n" + " mov r0, %0 \n" + " msr basepri, r0 \n" + " bl vTaskSwitchContext \n" + " mov r0, #0 \n" + " msr basepri, r0 \n" + " ldmia sp!, {r3, r14} \n" +#if configGDB_HELPER + "dbg_switch_to_pending_task: \n" + " ldr r3, _dbgPendingTaskHandle \n" /* --> Load task handle going to switch to <-- */ +#endif /* configGDB_HELPER */ + " ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " ldr r0, [r1] \n" +#if configENABLE_FPU + " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers */ + " tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the high vfp registers too. */ + " it eq \n" + " vldmiaeq r0!, {s16-s31} \n" +#else + " ldmia r0!, {r4-r11} \n" /* Pop the core registers. */ +#endif + " msr psp, r0 \n" +#if configGDB_HELPER + " bkpt \n" /* <-- here debugger stops and steps out to target task context */ +#endif /* configGDB_HELPER */ + " bx r14 \n" + " \n" + " .align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB \n" +#if configGDB_HELPER + "_dbgPendSVHookState: .word dbgPendSVHookState \n" + "_dbgPendingTaskHandle: .word dbgPendingTaskHandle \n" + ".word dbgFreeRTOSConfig_suspend_value \n" /* force keep these symbols from cutting away by linker garbage collector */ + ".word dbgFreeRTOSConfig_delete_value \n" +#endif + ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) + ); +#else /* Cortex M0+ */ + __asm volatile ( + " mrs r0, psp \n" + " \n" + " ldr r3, pxCurrentTCBConstG \n" /* Get the location of the current TCB. */ + " ldr r2, [r3] \n" + " \n" + " sub r0, r0, #32 \n" /* Make space for the remaining low registers. */ + " str r0, [r2] \n" /* Save the new top of stack. */ + " stmia r0!, {r4-r7} \n" /* Store the low registers that are not saved automatically. */ + " mov r4, r8 \n" /* Store the high registers. */ + " mov r5, r9 \n" + " mov r6, r10 \n" + " mov r7, r11 \n" + " stmia r0!, {r4-r7} \n" + " \n" + " push {r3, r14} \n" + " cpsid i \n" + " bl vTaskSwitchContext \n" + " cpsie i \n" + " pop {r2, r3} \n" /* lr goes in r3. r2 now holds tcb pointer. */ + " \n" + " ldr r1, [r2] \n" + " ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */ + " add r0, r0, #16 \n" /* Move to the high registers. */ + " ldmia r0!, {r4-r7} \n" /* Pop the high registers. */ + " mov r8, r4 \n" + " mov r9, r5 \n" + " mov r10, r6 \n" + " mov r11, r7 \n" + " \n" + " msr psp, r0 \n" /* Remember the new top of stack for the task. */ + " \n" + " sub r0, r0, #32 \n" /* Go back for the low registers that are not automatically restored. */ + " ldmia r0!, {r4-r7} \n" /* Pop low registers. */ + " \n" + " bx r3 \n" + " \n" + ".align 2 \n" + "pxCurrentTCBConstG: .word pxCurrentTCB" + ); +#endif +} + +#endif /* configGDB_HELPER */ + +#endif /* (configCOMPILER==configCOMPILER_ARM_GCC) */ +/*-----------------------------------------------------------*/ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* ARM M4(F)/M7/M33 core */ + +#if configCOMPILER==configCOMPILER_ARM_KEIL +__asm uint32_t vPortGetIPSR(void) { + PRESERVE8 + + mrs r0, ipsr + bx r14 +} +#endif + +#if( configASSERT_DEFINED == 1 ) + void vPortValidateInterruptPriority( void ) + { + uint32_t ulCurrentInterrupt; + uint8_t ucCurrentPriority; + + /* Obtain the number of the currently executing interrupt. */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + ulCurrentInterrupt = vPortGetIPSR(); + #else + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + #endif + + /* Is the interrupt number a user defined interrupt? */ + if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER ) + { + /* Look up the interrupt's priority. */ + ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ]; + + /* The following assertion will fail if a service routine (ISR) for + an interrupt that has been assigned a priority above + configMAX_SYSCALL_INTERRUPT_PRIORITY calls an ISR safe FreeRTOS API + function. ISR safe FreeRTOS API functions must *only* be called + from interrupts that have been assigned a priority at or below + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Numerically low interrupt priority numbers represent logically high + interrupt priorities, therefore the priority of the interrupt must + be set to a value equal to or numerically *higher* than + configMAX_SYSCALL_INTERRUPT_PRIORITY. + + Interrupts that use the FreeRTOS API must not be left at their + default priority of zero as that is the highest possible priority, + which is guaranteed to be above configMAX_SYSCALL_INTERRUPT_PRIORITY, + and therefore also guaranteed to be invalid. + + FreeRTOS maintains separate thread and ISR API functions to ensure + interrupt entry is as fast and simple as possible. + + The following links provide detailed information: + http://www.freertos.org/RTOS-Cortex-M3-M4.html + http://www.freertos.org/FAQHelp.html */ + configASSERT( ucCurrentPriority >= ucMaxSysCallPriority ); + } + + /* Priority grouping: The interrupt controller (NVIC) allows the bits + that define each interrupt's priority to be split between bits that + define the interrupt's pre-emption priority bits and bits that define + the interrupt's sub-priority. For simplicity all bits must be defined + to be pre-emption priority bits. The following assertion will fail if + this is not the case (if some bits represent a sub-priority). + + If the application only uses CMSIS libraries for interrupt + configuration then the correct setting can be achieved on all Cortex-M + devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the + scheduler. Note however that some vendor specific peripheral libraries + assume a non-zero priority group setting, in which cases using a value + of zero will result in unpredicable behaviour. */ + configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue ); + } + +#endif /* configASSERT_DEFINED */ + +#endif /* ARM M4(F) core */ + +#endif /* MCUC1_CONFIG_SDK_USE_FREERTOS */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portTicks.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portTicks.h new file mode 100644 index 0000000..f69c990 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portTicks.h @@ -0,0 +1,114 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PORTTICKS_H_ +#define PORTTICKS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Interface header file to the Processor Expert Tick counter. + * This file is used to access the interface, especially for performance + * counters (e.g. for Percepio Trace). + * That way the a module can interface this wrapper header file instead + * of one of the standard FreeRTOS header files. + */ +#include "MCUC1.h" /* include SDK and API used */ + +#if MCUC1_CONFIG_SDK_VERSION_USED == MCUC1_CONFIG_SDK_PROCESSOR_EXPERT + #include "Cpu.h" /* include CPU module because of dependency to CPU clock rate */ +#endif +#include "FreeRTOSConfig.h" +#include "portmacro.h" + +#if !MCUC1_CONFIG_PEX_SDK_USED + extern uint32_t SystemCoreClock; /* in Kinetis SDK, this contains the system core clock speed */ +#endif + +/*! + * \brief Return the tick raw counter value. It is assumed that the counter register has been reset at the last tick time + * \return Tick counter value. The value is reset at tick interrupt time. + * */ +uint32_t uxGetTickCounterValue(void); + +#if configSYSTICK_USE_LOW_POWER_TIMER + #define FREERTOS_HWTC_DOWN_COUNTER 0 /* LPTM is counting up */ + #define FREERTOS_HWTC_PERIOD ((1000/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ)-1UL) /* counter is incrementing from zero to this value */ +#else + #define FREERTOS_HWTC_DOWN_COUNTER 1 /* SysTick is counting down */ + #define FREERTOS_HWTC_PERIOD ((configCPU_CLOCK_HZ/configTICK_RATE_HZ)-1UL) /* counter is decrementing from this value to zero */ +#endif + +#if configUSE_TICKLESS_IDLE == 1 + extern volatile uint8_t portTickCntr; /* used to find out if we woke up by the tick interrupt */ +#endif + +#define FREERTOS_HWTC_FREQ_HZ configTICK_RATE_HZ + +#if configUSE_PERCEPIO_TRACE_HOOKS /* using Percepio Trace */ +#if (TRC_CFG_HARDWARE_PORT == TRC_HARDWARE_PORT_PROCESSOR_EXPERT) + /* tick information for Percepio Trace */ + + /* undefine previous values, where dummy anyway: make sure this header file is included last! */ + #undef TRC_HWTC_COUNT_DIRECTION + #undef TRC_HWTC_PERIOD + #undef TRC_HWTC_DIVISOR + #undef TRC_HWTC_COUNT + + #if FREERTOS_HWTC_DOWN_COUNTER + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_DECREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is decrementing from this value to zero */ + #else + #define TRC_HWTC_COUNT_DIRECTION DIRECTION_INCREMENTING + #define TRC_HWTC_PERIOD FREERTOS_HWTC_PERIOD /* counter is incrementing from zero to this value */ + #endif + + #if configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #if configSYSTICK_USE_LOW_POWER_TIMER + #define TRC_HWTC_DIVISOR 1 /* divisor for slow counter tick value */ + #else + #define TRC_HWTC_DIVISOR 2 /* divisor for fast counter tick value */ + #endif + #else + #define TRC_HWTC_DIVISOR 1 + #endif + + #define TRC_HWTC_COUNT (uxGetTickCounterValue()) + #define TRC_HWTC_TYPE TRC_FREE_RUNNING_32BIT_INCR + #define TRC_IRQ_PRIORITY_ORDER 0 /* 0: lower IRQ prios mean higher priority, 1: otherwise */ + #define TRC_HWTC_FREQ_HZ FREERTOS_HWTC_FREQ_HZ +#endif +#endif /* configUSE_PERCEPIO_TRACE_HOOKS */ + +#ifdef __cplusplus +} +#endif + +#endif /* PORTTICKS_H_ */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portable.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portable.h new file mode 100644 index 0000000..90ae895 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portable.h @@ -0,0 +1,183 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/*----------------------------------------------------------- + * Portable layer API. Each function must be defined for each port. + *----------------------------------------------------------*/ + +#ifndef PORTABLE_H +#define PORTABLE_H + +/* Each FreeRTOS port has a unique portmacro.h header file. Originally a +pre-processor definition was used to ensure the pre-processor found the correct +portmacro.h file for the port being used. That scheme was deprecated in favour +of setting the compiler's include path such that it found the correct +portmacro.h file - removing the need for the constant and allowing the +portmacro.h file to be located anywhere in relation to the port being used. +Purely for reasons of backward compatibility the old method is still valid, but +to make it clear that new projects should not use it, support for the port +specific constants has been moved into the deprecated_definitions.h header +file. */ +#include "deprecated_definitions.h" + +/* If portENTER_CRITICAL is not defined then including deprecated_definitions.h +did not result in a portmacro.h header file being included - and it should be +included here. In this case the path to the correct portmacro.h header file +must be set in the compiler's include path. */ +#ifndef portENTER_CRITICAL + #include "portmacro.h" +#endif + +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#endif + +#if portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#endif + +#if portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#endif + +#if portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#endif + +#if portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#endif + +#if portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#endif + +#ifndef portBYTE_ALIGNMENT_MASK + #error "Invalid portBYTE_ALIGNMENT definition" +#endif + +#ifndef portNUM_CONFIGURABLE_REGIONS + #define portNUM_CONFIGURABLE_REGIONS 1 +#endif + +#ifndef portHAS_STACK_OVERFLOW_CHECKING + #define portHAS_STACK_OVERFLOW_CHECKING 0 +#endif + +#ifndef portARCH_NAME + #define portARCH_NAME NULL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mpu_wrappers.h" + +/* + * Setup the stack of a new task so it is ready to be placed under the + * scheduler control. The registers have to be placed on the stack in + * the order that the port expects to find them. + * + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters, BaseType_t xRunPrivileged ) PRIVILEGED_FUNCTION; + #endif +#else + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, StackType_t *pxEndOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #else + StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters ) PRIVILEGED_FUNCTION; + #endif +#endif + +/* Used by heap_5.c. */ +typedef struct HeapRegion +{ + uint8_t *pucStartAddress; + size_t xSizeInBytes; +} HeapRegion_t; + +/* + * Used to define multiple heap regions for use by heap_5.c. This function + * must be called before any calls to pvPortMalloc() - not creating a task, + * queue, semaphore, mutex, software timer, event group, etc. will result in + * pvPortMalloc being called. + * + * pxHeapRegions passes in an array of HeapRegion_t structures - each of which + * defines a region of memory that can be used as the heap. The array is + * terminated by a HeapRegions_t structure that has a size of 0. The region + * with the lowest start address must appear first in the array. + */ +void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEGED_FUNCTION; + + +/* + * Map to the memory management routines required for the port. + */ +void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; +void vPortFree( void *pv ) PRIVILEGED_FUNCTION; +void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; +size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; +size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; +void vPortInitializeHeap(void) PRIVILEGED_FUNCTION; /* << EST */ + +/* + * Setup the hardware ready for the scheduler to take control. This generally + * sets up a tick interrupt and sets timers for the correct tick frequency. + */ +BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * Undo any hardware/ISR setup that was performed by xPortStartScheduler() so + * the hardware is left in its original condition after the scheduler stops + * executing. + */ +void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; + +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, StackType_t *pxBottomOfStack, uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTABLE_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portasm.s b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portasm.s new file mode 100644 index 0000000..255f7c4 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portasm.s @@ -0,0 +1,28 @@ +/* file is intentionally empty as not needed for this GNU gcc FreeRTOS port */ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portmacro.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portmacro.h new file mode 100644 index 0000000..b3299c6 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/portmacro.h @@ -0,0 +1,604 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef PORTMACRO_H +#define PORTMACRO_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "FreeRTOSConfig.h" +#include "projdefs.h" /* for pdFALSE, pdTRUE */ + +void vPortStopTickTimer(void); +/*----------------------------------------------------------- + * Port specific definitions. + * + * The settings in this file configure FreeRTOS correctly for the + * given hardware and compiler. + * + * These settings should not be altered. + *----------------------------------------------------------- + */ +#ifndef configENABLE_FPU + #error configENABLE_FPU must be defined in FreeRTOSConfig.h. Set configENABLE_FPU to 1 to enable the FPU or 0 to disable the FPU. +#endif /* configENABLE_FPU */ + +#ifndef configENABLE_MPU + #error configENABLE_MPU must be defined in FreeRTOSConfig.h. Set configENABLE_MPU to 1 to enable the MPU or 0 to disable the MPU. +#endif /* configENABLE_MPU */ + +#ifndef configENABLE_TRUSTZONE + #error configENABLE_TRUSTZONE must be defined in FreeRTOSConfig.h. Set configENABLE_TRUSTZONE to 1 to enable TrustZone or 0 to disable TrustZone. +#endif /* configENABLE_TRUSTZONE */ + +#if (configCOMPILER==configCOMPILER_S12_FSL) || (configCOMPILER==configCOMPILER_S08_FSL) + /* disabling some warnings as the RTOS sources are not that clean... */ + #pragma MESSAGE DISABLE C5909 /* assignment in condition */ + #pragma MESSAGE DISABLE C2705 /* possible loss of data */ + #pragma MESSAGE DISABLE C5905 /* multiplication with one */ + #pragma MESSAGE DISABLE C5904 /* division by one */ + #pragma MESSAGE DISABLE C5660 /* removed dead code */ + #pragma MESSAGE DISABLE C5917 /* removed dead assignment */ + #pragma MESSAGE DISABLE C4001 /* condition always FALSE */ +#endif +#if configCOMPILER==configCOMPILER_S12_FSL + #pragma MESSAGE DISABLE C12053 /* SP change not in debug information */ + #pragma MESSAGE DISABLE C12056 /* SP debug information incorrect */ +#endif + +/* Type definitions. */ +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portSTACK_TYPE unsigned long +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portSTACK_TYPE unsigned char +#endif +typedef portSTACK_TYPE StackType_t; + +#define portUSE_CUSTOM_BASE_TYPE 0 /* 1: use custom base type */ + +#if portUSE_CUSTOM_BASE_TYPE + #define portBASE_TYPE char /* custom port base type */ + typedef portBASE_TYPE BaseType_t; + typedef unsigned portBASE_TYPE UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) || (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBASE_TYPE long + typedef long BaseType_t; + typedef unsigned long UBaseType_t; +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBASE_TYPE char + typedef signed char BaseType_t; + typedef unsigned char UBaseType_t; +#endif + +#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)0xffffffff + +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) || configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + /* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ + #define portTICK_TYPE_IS_ATOMIC 1 +#endif /* 32bit architecture */ + +#endif + +#if( configENABLE_TRUSTZONE == 1 ) + extern void vPortAllocateSecureContext( uint32_t ulSecureStackSize ); + extern void vPortFreeSecureContext( uint32_t *pulTCB ) /* PRIVILEGED_FUNCTION */; +#endif /* configENABLE_TRUSTZONE */ + +#if( configENABLE_MPU == 1 ) + extern BaseType_t xIsPrivileged( void ) /* __attribute__ (( naked )) */; + extern void vResetPrivilege( void ) /* __attribute__ (( naked )) */; +#endif /* configENABLE_MPU */ + +/** + * @brief MPU specific constants. + */ +#if( configENABLE_MPU == 1 ) + #define portUSING_MPU_WRAPPERS 1 + #define portPRIVILEGE_BIT ( 0x80000000UL ) +#else + #define portPRIVILEGE_BIT ( 0x0UL ) +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU +/*-----------------------------------------------------------*/ +/* MPU specific constants. */ + +#define portMPU_REGION_READ_WRITE ( 0x03UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 0x05UL << 24UL ) +#define portMPU_REGION_READ_ONLY ( 0x06UL << 24UL ) +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0x01UL << 24UL ) +#define portMPU_REGION_CACHEABLE_BUFFERABLE ( 0x07UL << 16UL ) +#define portMPU_REGION_EXECUTE_NEVER ( 0x01UL << 28UL ) + +#define portUNPRIVILEGED_FLASH_REGION ( 0UL ) +#define portPRIVILEGED_FLASH_REGION ( 1UL ) +#define portPRIVILEGED_RAM_REGION ( 2UL ) +#define portGENERAL_PERIPHERALS_REGION ( 3UL ) +#define portSTACK_REGION ( 4UL ) +#define portFIRST_CONFIGURABLE_REGION ( 5UL ) +#define portLAST_CONFIGURABLE_REGION ( 7UL ) +#define portNUM_CONFIGURABLE_REGIONS ( ( portLAST_CONFIGURABLE_REGION - portFIRST_CONFIGURABLE_REGION ) + 1 ) +#define portTOTAL_NUM_REGIONS ( portNUM_CONFIGURABLE_REGIONS + 1 ) /* Plus one to make space for the stack region. */ + +#define portSWITCH_TO_USER_MODE() __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0 " :::"r0" ) + +typedef struct MPU_REGION_REGISTERS +{ + uint32_t ulRegionBaseAddress; + uint32_t ulRegionAttribute; +} xMPU_REGION_REGISTERS; + +/* Plus 1 to create space for the stack region. */ +typedef struct MPU_SETTINGS +{ + xMPU_REGION_REGISTERS xRegion[ portTOTAL_NUM_REGIONS ]; +} xMPU_SETTINGS; +#endif /* configENABLE_MPU */ + +#if configENABLE_MPU /* check values for LPC55xx! */ +/* Devices Region. */ +#define portDEVICE_REGION_START_ADDRESS ( 0x50000000 ) +#define portDEVICE_REGION_END_ADDRESS ( 0x5FFFFFFF ) + +/* Device memory attributes used in MPU_MAIR registers. + * + * 8-bit values encoded as follows: + * Bit[7:4] - 0000 - Device Memory + * Bit[3:2] - 00 --> Device-nGnRnE + * 01 --> Device-nGnRE + * 10 --> Device-nGRE + * 11 --> Device-GRE + * Bit[1:0] - 00, Reserved. + */ +#define portMPU_DEVICE_MEMORY_nGnRnE ( 0x00 ) /* 0000 0000 */ +#define portMPU_DEVICE_MEMORY_nGnRE ( 0x04 ) /* 0000 0100 */ +#define portMPU_DEVICE_MEMORY_nGRE ( 0x08 ) /* 0000 1000 */ +#define portMPU_DEVICE_MEMORY_GRE ( 0x0C ) /* 0000 1100 */ + +/* Normal memory attributes used in MPU_MAIR registers. */ +#define portMPU_NORMAL_MEMORY_NON_CACHEABLE ( 0x44 ) /* Non-cacheable. */ +#define portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE ( 0xFF ) /* Non-Transient, Write-back, Read-Allocate and Write-Allocate. */ + +/* Attributes used in MPU_RBAR registers. */ +#define portMPU_REGION_NON_SHAREABLE ( 0UL << 3UL ) +#define portMPU_REGION_INNER_SHAREABLE ( 1UL << 3UL ) +#define portMPU_REGION_OUTER_SHAREABLE ( 2UL << 3UL ) + +#define portMPU_REGION_PRIVILEGED_READ_WRITE ( 0UL << 1UL ) +#define portMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define portMPU_REGION_PRIVILEGED_READ_ONLY ( 2UL << 1UL ) +#define portMPU_REGION_READ_ONLY ( 3UL << 1UL ) + +#define portMPU_REGION_EXECUTE_NEVER ( 1UL ) + +/*-----------------------------------------------------------*/ + +/** + * @brief Settings to define an MPU region. + */ +typedef struct MPURegionSettings +{ + uint32_t ulRBAR; /**< RBAR for the region. */ + uint32_t ulRLAR; /**< RLAR for the region. */ +} MPURegionSettings_t; + +/** + * @brief MPU settings as stored in the TCB. + */ +typedef struct MPU_SETTINGS +{ + uint32_t ulMAIR0; /**< MAIR0 for the task containing attributes for all the 4 per task regions. */ + MPURegionSettings_t xRegionsSettings[ portTOTAL_NUM_REGIONS ]; /**< Settings for 4 per task regions. */ +} xMPU_SETTINGS; + +/*-----------------------------------------------------------*/ + +/** + * @brief SVC numbers. + */ +#define portSVC_ALLOCATE_SECURE_CONTEXT 0 +#define portSVC_FREE_SECURE_CONTEXT 1 +#define portSVC_START_SCHEDULER 2 +#define portSVC_RAISE_PRIVILEGE 3 +/*-----------------------------------------------------------*/ + +#endif /* configENABLE_MPU */ + +/*-----------------------------------------------------------*/ +/* Hardware specifics. */ +#if (configCPU_FAMILY==configCPU_FAMILY_CF1) || (configCPU_FAMILY==configCPU_FAMILY_CF2) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif configCPU_FAMILY_IS_ARM(configCPU_FAMILY) + #define portBYTE_ALIGNMENT 8 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_S08) || (configCPU_FAMILY==configCPU_FAMILY_S12) + #define portBYTE_ALIGNMENT 1 + #define portSTACK_GROWTH -1 /* stack grows from HIGH to LOW */ +#elif (configCPU_FAMILY==configCPU_FAMILY_DSC) + #define portBYTE_ALIGNMENT 4 + #define portSTACK_GROWTH 1 /* stack grows from LOW to HIGH */ +#endif + +#define portTICK_PERIOD_MS ((TickType_t)1000/configTICK_RATE_HZ) +/*-----------------------------------------------------------*/ +/* Critical section management. */ +unsigned long ulPortSetIPL(unsigned portLONG); + +/* If set to 1, then this port uses the critical nesting count from the TCB rather than +maintaining a separate value and then saving this value in the task stack. */ +#define portCRITICAL_NESTING_IN_TCB 0 + + +extern unsigned portBASE_TYPE uxPortSetInterruptMaskFromISR(void); +extern void vPortClearInterruptMaskFromISR(unsigned portBASE_TYPE); + + +#if configCOMPILER==configCOMPILER_DSC_FSL + /* for DSC, there is a possible skew after enable/disable Interrupts. */ + #define portPOST_ENABLE_DISABLE_INTERRUPTS() \ + asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); asm(nop); +#else + #define portPOST_ENABLE_DISABLE_INTERRUPTS() /* nothing special needed */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) || configCPU_FAMILY_IS_ARM_M33(configCPU_FAMILY) /* Cortex M4/M7/M33 */ + #if (configCOMPILER==configCOMPILER_ARM_KEIL) + __asm uint32_t ulPortSetInterruptMask(void); + __asm void vPortClearInterruptMask(uint32_t ulNewMask); + + #define portSET_INTERRUPT_MASK() ulPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask(0) + #elif (configCOMPILER==configCOMPILER_ARM_GCC) + /* + * Set basepri to portMAX_SYSCALL_INTERRUPT_PRIORITY without effecting other + * registers. r0 is clobbered. + */ + #define portSET_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, %0 \n" \ + " msr basepri, r0 \n" \ + : /* no output operands */ \ + :"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY) /* input */\ + :"r0" /* clobber */ \ + ) + /* + * Set basepri back to 0 without effective other registers. + * r0 is clobbered. + */ + #define portCLEAR_INTERRUPT_MASK() \ + __asm volatile \ + ( \ + " mov r0, #0 \n" \ + " msr basepri, r0 \n" \ + : /* no output */ \ + : /* no input */ \ + :"r0" /* clobber */ \ + ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) /* IAR */ || (configCOMPILER==configCOMPILER_ARM_FSL) /* legacy FSL ARM Compiler */ + void vPortSetInterruptMask(void); /* prototype, implemented in portasm.s */ + void vPortClearInterruptMask(void); /* prototype, implemented in portasm.s */ + #define portSET_INTERRUPT_MASK() vPortSetInterruptMask() + #define portCLEAR_INTERRUPT_MASK() vPortClearInterruptMask() + #else + #error "unknown compiler?" + #endif +#elif configCPU_FAMILY_IS_ARM_M0(configCPU_FAMILY) /* Cortex-M0+ */ + #if configCOMPILER==configCOMPILER_ARM_KEIL + #define portSET_INTERRUPT_MASK() __disable_irq() + #define portCLEAR_INTERRUPT_MASK() __enable_irq() + #else /* IAR, CW ARM or GNU ARM gcc */ + #define portSET_INTERRUPT_MASK() __asm volatile("cpsid i") + #define portCLEAR_INTERRUPT_MASK() __asm volatile("cpsie i") + #endif +#endif + +/* Critical section management. */ +extern void vPortEnterCritical(void); +extern void vPortExitCritical(void); +#define portSET_INTERRUPT_MASK_FROM_ISR() 0;portSET_INTERRUPT_MASK() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) portCLEAR_INTERRUPT_MASK();(void)x +#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK() +#define portENABLE_INTERRUPTS() portCLEAR_INTERRUPT_MASK() +#define portENTER_CRITICAL() vPortEnterCritical() +#define portEXIT_CRITICAL() vPortExitCritical() +#if configCOMPILER==configCOMPILER_ARM_KEIL + #define portDISABLE_ALL_INTERRUPTS() __disable_irq() + #define portENABLE_ALL_INTERRUPTS() __enable_irq() +#else /* IAR, CW ARM or GNU ARM gcc */ + #define portDISABLE_ALL_INTERRUPTS() __asm volatile("cpsid i") + #define portENABLE_ALL_INTERRUPTS() __asm volatile("cpsie i") +#endif + +/* There are an uneven number of items on the initial stack, so +portALIGNMENT_ASSERT_pxCurrentTCB() will trigger false positive asserts. */ +#define portALIGNMENT_ASSERT_pxCurrentTCB (void) + +#if( configENABLE_TRUSTZONE == 1 ) + /** + * @brief Allocate a secure context for the task. + * + * Tasks are not created with a secure context. Any task that is going to call + * secure functions must call portALLOCATE_SECURE_CONTEXT() to allocate itself a + * secure context before it calls any secure function. + * + * @param[in] ulSecureStackSize The size of the secure stack to be allocated. + */ + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) vPortAllocateSecureContext( ulSecureStackSize ) + + /** + * @brief Called when a task is deleted to delete the task's secure context, + * if it has one. + * + * @param[in] pxTCB The TCB of the task being deleted. + */ + #define portCLEAN_UP_TCB( pxTCB ) vPortFreeSecureContext( ( uint32_t * ) pxTCB ) +#else + #define portALLOCATE_SECURE_CONTEXT( ulSecureStackSize ) + #define portCLEAN_UP_TCB( pxTCB ) +#endif /* configENABLE_TRUSTZONE */ + +/*-----------------------------------------------------------*/ + +#if( configENABLE_MPU == 1 ) + /** + * @brief Checks whether or not the processor is privileged. + * + * @return 1 if the processor is already privileged, 0 otherwise. + */ + #define portIS_PRIVILEGED() xIsPrivileged() + + /** + * @brief Raise an SVC request to raise privilege. + * + * The SVC handler checks that the SVC was raised from a system call and only + * then it raises the privilege. If this is called from any other place, + * the privilege is not raised. + */ + #define portRAISE_PRIVILEGE() __asm volatile ( "svc %0 \n" :: "i" ( portSVC_RAISE_PRIVILEGE ) : "memory" ); + + /** + * @brief Lowers the privilege level by setting the bit 0 of the CONTROL + * register. + */ + #define portRESET_PRIVILEGE() vResetPrivilege() +#else + #define portIS_PRIVILEGED() + #define portRAISE_PRIVILEGE() + #define portRESET_PRIVILEGE() +#endif /* configENABLE_MPU */ +/*-----------------------------------------------------------*/ + + +/*-----------------------------------------------------------*/ +/* Scheduler utilities. */ + +extern void vPortYieldFromISR(void); +#define portYIELD() vPortYieldFromISR() +#define portEND_SWITCHING_ISR(xSwitchRequired) { if( xSwitchRequired != pdFALSE ) { traceISR_EXIT_TO_SCHEDULER(); portYIELD(); } else { traceISR_EXIT(); } } +#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x) +/*-----------------------------------------------------------*/ + +/* Architecture specific optimizations. */ +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) + #if configUSE_PORT_OPTIMISED_TASK_SELECTION == 1 + /* Generic helper function. */ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + __attribute__((always_inline)) static inline unsigned char ucPortCountLeadingZeros(unsigned long ulBitmap) + { + uint8_t ucReturn; + + __asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) ); + return ucReturn; + } + #endif + /* Check the configuration. */ + #if( configMAX_PRIORITIES > 32 ) + #error configUSE_PORT_OPTIMISED_TASK_SELECTION can only be set to 1 when configMAX_PRIORITIES is less than or equal to 32. It is very rare that a system requires more than 10 to 15 difference priorities as tasks that share a priority will time slice. + #endif + + /* Store/clear the ready priorities in a bit map. */ + #define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) + #define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) + + /*-----------------------------------------------------------*/ + #if (configCOMPILER==configCOMPILER_ARM_GCC) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_KEIL) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( uint32_t ) __clz( ( uxReadyPriorities ) ) ) + #elif (configCOMPILER==configCOMPILER_ARM_IAR) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) uxTopPriority = ( 31UL - ( ( uint32_t ) __CLZ( ( uxReadyPriorities ) ) ) ) + #endif + + #endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ +#endif /* configCPU_FAMILY_IS_ARM_M4_M7 */ +/*-----------------------------------------------------------*/ + +#ifdef configASSERT +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) /* ARM M4/M7(F) core */ + void vPortValidateInterruptPriority( void ); + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() +#else + #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() +#endif +#endif + +/*-----------------------------------------------------------*/ +/* 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 +/*-----------------------------------------------------------*/ +/* 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) +/*-----------------------------------------------------------*/ +void vPortStartFirstTask(void); + /* starts the first task, called from xPortStartScheduler() */ + +void vPortYieldHandler(void); + /* handler for the SWI interrupt */ + +#if configENABLE_FPU /* has floating point unit */ + void vPortEnableVFP(void); + /* enables floating point support in the CPU */ +#endif + +/* Prototypes for interrupt service handlers */ +#if !MCUC1_CONFIG_PEX_SDK_USED /* the SDK expects different interrupt handler names */ + void SVC_Handler(void); /* SVC interrupt handler */ + void PendSV_Handler(void); /* PendSV interrupt handler */ + void SysTick_Handler(void); /* Systick interrupt handler */ +#else + void vPortSVCHandler(void); /* SVC interrupt handler */ + void vPortPendSVHandler(void); /* PendSV interrupt handler */ + void vPortTickHandler(void); /* Systick interrupt handler */ +#endif + +#if configCPU_FAMILY_IS_ARM_M4_M7(configCPU_FAMILY) && (configCOMPILER==configCOMPILER_ARM_GCC) + #define portINLINE __inline + + #ifndef portFORCE_INLINE + #define portFORCE_INLINE inline __attribute__(( always_inline)) + #endif + + #if configENABLE_MPU + /* Set the privilege level to user mode if xRunningPrivileged is false. */ + portFORCE_INLINE static void vPortResetPrivilege( BaseType_t xRunningPrivileged ) + { + if( xRunningPrivileged != pdTRUE ) + { + __asm volatile ( " mrs r0, control \n" \ + " orr r0, #1 \n" \ + " msr control, r0 \n" \ + :::"r0" ); + } + } + #endif + + portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void ) + { + uint32_t ulCurrentInterrupt; + BaseType_t xReturn; + + /* Obtain the number of the currently executing interrupt. */ + __asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) ); + + if( ulCurrentInterrupt == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + + return xReturn; + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortRaiseBASEPRI( void ) + { + uint32_t ulNewBASEPRI; + + __asm volatile + ( + " mov %0, %1 \n" \ + " msr basepri, %0 \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + } + + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static uint32_t ulPortRaiseBASEPRI( void ) + { + uint32_t ulOriginalBASEPRI, ulNewBASEPRI; + + __asm volatile + ( + " mrs %0, basepri \n" \ + " mov %1, %2 \n" \ + " msr basepri, \n" \ + " isb \n" \ + " dsb \n" \ + :"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) + ); + + /* This return will not be reached but is necessary to prevent compiler + warnings. */ + return ulOriginalBASEPRI; + } + /*-----------------------------------------------------------*/ + + portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue ) + { + __asm volatile + ( + " msr basepri, %0 " :: "r" ( ulNewMaskValue ) + ); + } + /*-----------------------------------------------------------*/ +#endif + +#if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + BaseType_t configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME(void); /* return pdTRUE if RTOS can enter tickless idle mode, pdFALSE otherwise */ +#endif + +void prvTaskExitError(void); + /* handler to catch task exit errors */ + +#if !configGENERATE_RUN_TIME_STATS_USE_TICKS + extern void FRTOS1_AppConfigureTimerForRuntimeStats(void); + extern uint32_t FRTOS1_AppGetRuntimeCounterValueFromISR(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PORTMACRO_H */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/projdefs.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/projdefs.h new file mode 100644 index 0000000..762e5c7 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/projdefs.h @@ -0,0 +1,125 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef PROJDEFS_H +#define PROJDEFS_H + +/* + * Defines the prototype to which task functions must conform. Defined in this + * file to ensure the type is known before portable.h is included. + */ +typedef void (*TaskFunction_t)( void * ); + +/* Converts a time in milliseconds to a time in ticks. This macro can be +overridden by a macro of the same name defined in FreeRTOSConfig.h in case the +definition here is not suitable for your application. */ +#ifndef pdMS_TO_TICKS + #define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) ) +#endif + +#define pdFALSE ( ( BaseType_t ) 0 ) +#define pdTRUE ( ( BaseType_t ) 1 ) + +#define pdPASS ( pdTRUE ) +#define pdFAIL ( pdFALSE ) +#define errQUEUE_EMPTY ( ( BaseType_t ) 0 ) +#define errQUEUE_FULL ( ( BaseType_t ) 0 ) + +/* FreeRTOS error definitions. */ +#define errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ( -1 ) +#define errQUEUE_BLOCKED ( -4 ) +#define errQUEUE_YIELD ( -5 ) + +/* Macros used for basic data corruption checks. */ +#ifndef configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES + #define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 +#endif + +#if( configUSE_16_BIT_TICKS == 1 ) + #define pdINTEGRITY_CHECK_VALUE 0x5a5a +#else + #define pdINTEGRITY_CHECK_VALUE 0x5a5a5a5aUL +#endif + +/* The following errno values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_ERRNO_NONE 0 /* No errors */ +#define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */ +#define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */ +#define pdFREERTOS_ERRNO_EIO 5 /* I/O error */ +#define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */ +#define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */ +#define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */ +#define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */ +#define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */ +#define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */ +#define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */ +#define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */ +#define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */ +#define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */ +#define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */ +#define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */ +#define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */ +#define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */ +#define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */ +#define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */ +#define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */ +#define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */ +#define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */ +#define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */ +#define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */ +#define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */ +#define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */ +#define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */ +#define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */ +#define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */ +#define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */ +#define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */ +#define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */ +#define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */ +#define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */ +#define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */ +#define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */ +#define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */ +#define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */ + +/* The following endian values are used by FreeRTOS+ components, not FreeRTOS +itself. */ +#define pdFREERTOS_LITTLE_ENDIAN 0 +#define pdFREERTOS_BIG_ENDIAN 1 + +/* Re-defining endian values for generic naming. */ +#define pdLITTLE_ENDIAN pdFREERTOS_LITTLE_ENDIAN +#define pdBIG_ENDIAN pdFREERTOS_BIG_ENDIAN + + +#endif /* PROJDEFS_H */ + + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.c new file mode 100644 index 0000000..3caadde --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.c @@ -0,0 +1,2947 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" + +#if ( configUSE_CO_ROUTINES == 1 ) + #include "croutine.h" +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + + +/* Constants used with the cRxLock and cTxLock structure members. */ +#define queueUNLOCKED ( ( int8_t ) -1 ) +#define queueLOCKED_UNMODIFIED ( ( int8_t ) 0 ) + +/* When the Queue_t structure is used to represent a base queue its pcHead and +pcTail members are used as pointers into the queue storage area. When the +Queue_t structure is used to represent a mutex pcHead and pcTail pointers are +not necessary, and the pcHead pointer is set to NULL to indicate that the +structure instead holds a pointer to the mutex holder (if any). Map alternative +names to the pcHead and structure member to ensure the readability of the code +is maintained. The QueuePointers_t and SemaphoreData_t types are used to form +a union as their usage is mutually exclusive dependent on what the queue is +being used for. */ +#define uxQueueType pcHead +#define queueQUEUE_IS_MUTEX NULL + +typedef struct QueuePointers +{ + int8_t *pcTail; /*< Points to the byte at the end of the queue storage area. Once more byte is allocated than necessary to store the queue items, this is used as a marker. */ + int8_t *pcReadFrom; /*< Points to the last place that a queued item was read from when the structure is used as a queue. */ +} QueuePointers_t; + +typedef struct SemaphoreData +{ + TaskHandle_t xMutexHolder; /*< The handle of the task that holds the mutex. */ + UBaseType_t uxRecursiveCallCount;/*< Maintains a count of the number of times a recursive mutex has been recursively 'taken' when the structure is used as a mutex. */ +} SemaphoreData_t; + +/* Semaphores do not actually store or copy data, so have an item size of +zero. */ +#define queueSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0 ) +#define queueMUTEX_GIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define queueYIELD_IF_USING_PREEMPTION() +#else + #define queueYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* + * Definition of the queue used by the scheduler. + * Items are queued by copy, not reference. See the following link for the + * rationale: https://www.freertos.org/Embedded-RTOS-Queues.html + */ +typedef struct QueueDefinition /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + int8_t *pcHead; /*< Points to the beginning of the queue storage area. */ + int8_t *pcWriteTo; /*< Points to the free next place in the storage area. */ + + union + { + QueuePointers_t xQueue; /*< Data required exclusively when this structure is used as a queue. */ + SemaphoreData_t xSemaphore; /*< Data required exclusively when this structure is used as a semaphore. */ + } u; + + List_t xTasksWaitingToSend; /*< List of tasks that are blocked waiting to post onto this queue. Stored in priority order. */ + List_t xTasksWaitingToReceive; /*< List of tasks that are blocked waiting to read from this queue. Stored in priority order. */ + + volatile UBaseType_t uxMessagesWaiting;/*< The number of items currently in the queue. */ + UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */ + UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */ + + volatile int8_t cRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + volatile int8_t cTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */ + + #if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( configUSE_QUEUE_SETS == 1 ) + struct QueueDefinition *pxQueueSetContainer; + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxQueueNumber; + uint8_t ucQueueType; + #endif + +} xQUEUE; + +/* The old xQUEUE name is maintained above then typedefed to the new Queue_t +name below to enable the use of older kernel aware debuggers. */ +typedef xQUEUE Queue_t; + +/*-----------------------------------------------------------*/ + +/* + * The queue registry is just a means for kernel aware debuggers to locate + * queue structures. It has no other purpose so is an optional component. + */ +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + /* The type stored within the queue registry array. This allows a name + to be assigned to each queue making kernel aware debugging a little + more user friendly. */ + typedef struct QUEUE_REGISTRY_ITEM + { + const char *pcQueueName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + QueueHandle_t xHandle; + } xQueueRegistryItem; + + /* The old xQueueRegistryItem name is maintained above then typedefed to the + new xQueueRegistryItem name below to enable the use of older kernel aware + debuggers. */ + typedef xQueueRegistryItem QueueRegistryItem_t; + + /* The queue registry is simply an array of QueueRegistryItem_t structures. + The pcQueueName member of a structure being NULL is indicative of the + array position being vacant. */ + PRIVILEGED_DATA QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ]; + +#endif /* configQUEUE_REGISTRY_SIZE */ + +/* + * Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not + * prevent an ISR from adding or removing items to the queue, but does prevent + * an ISR from removing tasks from the queue event lists. If an ISR finds a + * queue is locked it will instead increment the appropriate queue lock count + * to indicate that a task may require unblocking. When the queue in unlocked + * these lock counts are inspected, and the appropriate action taken. + */ +static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any data in a queue. + * + * @return pdTRUE if the queue contains no items, otherwise pdFALSE. + */ +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Uses a critical section to determine if there is any space in a queue. + * + * @return pdTRUE if there is no space, otherwise pdFALSE; + */ +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) PRIVILEGED_FUNCTION; + +/* + * Copies an item into the queue, either at the front of the queue or the + * back of the queue. + */ +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) PRIVILEGED_FUNCTION; + +/* + * Copies an item out of a queue. + */ +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +#if ( configUSE_QUEUE_SETS == 1 ) + /* + * Checks to see if a queue is a member of a queue set, and if so, notifies + * the queue set that the queue contains data. + */ + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +#endif + +/* + * Called after a Queue_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; + +/* + * Mutexes are a special type of queue. When a mutex is created, first the + * queue is created, then prvInitialiseMutex() is called to configure the queue + * as a mutex. + */ +#if( configUSE_MUTEXES == 1 ) + static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION; +#endif + +#if( configUSE_MUTEXES == 1 ) + /* + * If a task waiting for a mutex causes the mutex holder to inherit a + * priority, but the waiting task times out, then the holder should + * disinherit the priority - but only down to the highest priority of any + * other tasks that are waiting for the same mutex. This function returns + * that priority. + */ + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) PRIVILEGED_FUNCTION; +#endif +/*-----------------------------------------------------------*/ + +/* + * Macro to mark a queue as locked. Locking a queue prevents an ISR from + * accessing the queue event lists. + */ +#define prvLockQueue( pxQueue ) \ + taskENTER_CRITICAL(); \ + { \ + if( ( pxQueue )->cRxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cRxLock = queueLOCKED_UNMODIFIED; \ + } \ + if( ( pxQueue )->cTxLock == queueUNLOCKED ) \ + { \ + ( pxQueue )->cTxLock = queueLOCKED_UNMODIFIED; \ + } \ + } \ + taskEXIT_CRITICAL() +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + pxQueue->u.xQueue.pcTail = pxQueue->pcHead + ( pxQueue->uxLength * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U; + pxQueue->pcWriteTo = pxQueue->pcHead; + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - 1U ) * pxQueue->uxItemSize ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + pxQueue->cRxLock = queueUNLOCKED; + pxQueue->cTxLock = queueUNLOCKED; + + if( xNewQueue == pdFALSE ) + { + /* If there are tasks blocked waiting to read from the queue, then + the tasks will remain blocked as after this function exits the queue + will still be empty. If there are tasks blocked waiting to write to + the queue, then one should be unblocked as after this function exits + it will be possible to write to it. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Ensure the event queues start in the correct state. */ + vListInitialise( &( pxQueue->xTasksWaitingToSend ) ); + vListInitialise( &( pxQueue->xTasksWaitingToReceive ) ); + } + } + taskEXIT_CRITICAL(); + + /* A value is returned for calling semantic consistency with previous + versions. */ + return pdPASS; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + /* The StaticQueue_t structure and the queue storage area must be + supplied. */ + configASSERT( pxStaticQueue != NULL ); + + /* A queue storage area should be provided if the item size is not 0, and + should not be provided if the item size is 0. */ + configASSERT( !( ( pucQueueStorage != NULL ) && ( uxItemSize == 0 ) ) ); + configASSERT( !( ( pucQueueStorage == NULL ) && ( uxItemSize != 0 ) ) ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticQueue_t or StaticSemaphore_t equals the size of + the real queue and semaphore structures. */ + volatile size_t xSize = sizeof( StaticQueue_t ); + configASSERT( xSize == sizeof( Queue_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* The address of a statically allocated queue was passed in, use it. + The address of a statically allocated storage area was also passed in + but is already set. */ + pxNewQueue = ( Queue_t * ) pxStaticQueue; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + + if( pxNewQueue != NULL ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Queues can be allocated wither statically or dynamically, so + note this queue was allocated statically in case the queue is + later deleted. */ + pxNewQueue->ucStaticallyAllocated = pdTRUE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) + { + Queue_t *pxNewQueue; + size_t xQueueSizeInBytes; + uint8_t *pucQueueStorage; + + configASSERT( uxQueueLength > ( UBaseType_t ) 0 ); + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* There is not going to be a queue storage area. */ + xQueueSizeInBytes = ( size_t ) 0; + } + else + { + /* Allocate enough space to hold the maximum number of items that + can be in the queue at any time. */ + xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + + /* Allocate the queue and storage area. Justification for MISRA + deviation as follows: pvPortMalloc() always ensures returned memory + blocks are aligned per the requirements of the MCU stack. In this case + pvPortMalloc() must return a pointer that is guaranteed to meet the + alignment requirements of the Queue_t structure - which in this case + is an int8_t *. Therefore, whenever the stack alignment requirements + are greater than or equal to the pointer to char requirements the cast + is safe. In other cases alignment requirements are not strict (one or + two bytes). */ + pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes ); /*lint !e9087 !e9079 see comment above. */ + + if( pxNewQueue != NULL ) + { + /* Jump past the queue structure to find the location of the queue + storage area. */ + pucQueueStorage = ( uint8_t * ) pxNewQueue; + pucQueueStorage += sizeof( Queue_t ); /*lint !e9016 Pointer arithmetic allowed on char types, especially when it assists conveying intent. */ + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* Queues can be created either statically or dynamically, so + note this task was created dynamically in case it is later + deleted. */ + pxNewQueue->ucStaticallyAllocated = pdFALSE; + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + prvInitialiseNewQueue( uxQueueLength, uxItemSize, pucQueueStorage, ucQueueType, pxNewQueue ); + } + else + { + traceQUEUE_CREATE_FAILED( ucQueueType ); + mtCOVERAGE_TEST_MARKER(); + } + + return pxNewQueue; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, const uint8_t ucQueueType, Queue_t *pxNewQueue ) +{ + /* Remove compiler warnings about unused parameters should + configUSE_TRACE_FACILITY not be set to 1. */ + ( void ) ucQueueType; + + if( uxItemSize == ( UBaseType_t ) 0 ) + { + /* No RAM was allocated for the queue storage area, but PC head cannot + be set to NULL because NULL is used as a key to say the queue is used as + a mutex. Therefore just set pcHead to point to the queue as a benign + value that is known to be within the memory map. */ + pxNewQueue->pcHead = ( int8_t * ) pxNewQueue; + } + else + { + /* Set the head to the start of the queue storage area. */ + pxNewQueue->pcHead = ( int8_t * ) pucQueueStorage; + } + + /* Initialise the queue members as described where the queue type is + defined. */ + pxNewQueue->uxLength = uxQueueLength; + pxNewQueue->uxItemSize = uxItemSize; + ( void ) xQueueGenericReset( pxNewQueue, pdTRUE ); + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + pxNewQueue->ucQueueType = ucQueueType; + } + #endif /* configUSE_TRACE_FACILITY */ + + #if( configUSE_QUEUE_SETS == 1 ) + { + pxNewQueue->pxQueueSetContainer = NULL; + } + #endif /* configUSE_QUEUE_SETS */ + + traceQUEUE_CREATE( pxNewQueue ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static void prvInitialiseMutex( Queue_t *pxNewQueue ) + { + if( pxNewQueue != NULL ) + { + /* The queue create function will set all the queue structure members + correctly for a generic queue, but this function is creating a + mutex. Overwrite those members that need to be set differently - + in particular the information required for priority inheritance. */ + pxNewQueue->u.xSemaphore.xMutexHolder = NULL; + pxNewQueue->uxQueueType = queueQUEUE_IS_MUTEX; + + /* In case this is a recursive mutex. */ + pxNewQueue->u.xSemaphore.uxRecursiveCallCount = 0; + + traceCREATE_MUTEX( pxNewQueue ); + + /* Start with the semaphore in the expected state. */ + ( void ) xQueueGenericSend( pxNewQueue, NULL, ( TickType_t ) 0U, queueSEND_TO_BACK ); + } + else + { + traceCREATE_MUTEX_FAILED(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + xNewQueue = xQueueGenericCreate( uxMutexLength, uxMutexSize, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_MUTEXES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xNewQueue; + const UBaseType_t uxMutexLength = ( UBaseType_t ) 1, uxMutexSize = ( UBaseType_t ) 0; + + /* Prevent compiler warnings about unused parameters if + configUSE_TRACE_FACILITY does not equal 1. */ + ( void ) ucQueueType; + + xNewQueue = xQueueGenericCreateStatic( uxMutexLength, uxMutexSize, NULL, pxStaticQueue, ucQueueType ); + prvInitialiseMutex( ( Queue_t * ) xNewQueue ); + + return xNewQueue; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + Queue_t * const pxSemaphore = ( Queue_t * ) xSemaphore; + + /* This function is called by xSemaphoreGetMutexHolder(), and should not + be called directly. Note: This is a good way of determining if the + calling task is the mutex holder, but not a good way of determining the + identity of the mutex holder, as the holder may change between the + following critical section exiting and the function returning. */ + taskENTER_CRITICAL(); + { + if( pxSemaphore->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = pxSemaphore->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + } + taskEXIT_CRITICAL(); + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_MUTEXES == 1 ) && ( INCLUDE_xSemaphoreGetMutexHolder == 1 ) ) + + TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) + { + TaskHandle_t pxReturn; + + configASSERT( xSemaphore ); + + /* Mutexes cannot be used in interrupt service routines, so the mutex + holder should not change in an ISR, and therefore a critical section is + not required here. */ + if( ( ( Queue_t * ) xSemaphore )->uxQueueType == queueQUEUE_IS_MUTEX ) + { + pxReturn = ( ( Queue_t * ) xSemaphore )->u.xSemaphore.xMutexHolder; + } + else + { + pxReturn = NULL; + } + + return pxReturn; + } /*lint !e818 xSemaphore cannot be a pointer to const because it is a typedef. */ + +#endif +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* If this is the task that holds the mutex then xMutexHolder will not + change outside of this task. If this task does not hold the mutex then + pxMutexHolder can never coincidentally equal the tasks handle, and as + this is the only condition we are interested in it does not matter if + pxMutexHolder is accessed simultaneously by another task. Therefore no + mutual exclusion is required to test the pxMutexHolder variable. */ + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + traceGIVE_MUTEX_RECURSIVE( pxMutex ); + + /* uxRecursiveCallCount cannot be zero if xMutexHolder is equal to + the task handle, therefore no underflow check is required. Also, + uxRecursiveCallCount is only modified by the mutex holder, and as + there can only be one, no mutual exclusion is required to modify the + uxRecursiveCallCount member. */ + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )--; + + /* Has the recursive call count unwound to 0? */ + if( pxMutex->u.xSemaphore.uxRecursiveCallCount == ( UBaseType_t ) 0 ) + { + /* Return the mutex. This will automatically unblock any other + task that might be waiting to access the mutex. */ + ( void ) xQueueGenericSend( pxMutex, NULL, queueMUTEX_GIVE_BLOCK_TIME, queueSEND_TO_BACK ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + /* The mutex cannot be given because the calling task is not the + holder. */ + xReturn = pdFAIL; + + traceGIVE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_RECURSIVE_MUTEXES == 1 ) + + BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxMutex = ( Queue_t * ) xMutex; + + configASSERT( pxMutex ); + + /* Comments regarding mutual exclusion as per those within + xQueueGiveMutexRecursive(). */ + + traceTAKE_MUTEX_RECURSIVE( pxMutex ); + + if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + xReturn = pdPASS; + } + else + { + xReturn = xQueueSemaphoreTake( pxMutex, xTicksToWait ); + + /* pdPASS will only be returned if the mutex was successfully + obtained. The calling task may have entered the Blocked state + before reaching here. */ + if( xReturn != pdFAIL ) + { + ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + } + else + { + traceTAKE_MUTEX_RECURSIVE_FAILED( pxMutex ); + } + } + + return xReturn; + } + +#endif /* configUSE_RECURSIVE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreateStatic( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticQueue, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) + { + QueueHandle_t xHandle; + + configASSERT( uxMaxCount != 0 ); + configASSERT( uxInitialCount <= uxMaxCount ); + + xHandle = xQueueGenericCreate( uxMaxCount, queueSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_COUNTING_SEMAPHORE ); + + if( xHandle != NULL ) + { + ( ( Queue_t * ) xHandle )->uxMessagesWaiting = uxInitialCount; + + traceCREATE_COUNTING_SEMAPHORE(); + } + else + { + traceCREATE_COUNTING_SEMAPHORE_FAILED(); + } + + return xHandle; + } + +#endif /* ( ( configUSE_COUNTING_SEMAPHORES == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) +{ +BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Is there room on the queue now? The running task must be the + highest priority task wanting to access the queue. If the head item + in the queue is to be overwritten then it does not matter if the + queue is full. */ + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + traceQUEUE_SEND( pxQueue ); + + #if ( configUSE_QUEUE_SETS == 1 ) + { + UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting; + + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) ) + { + /* Do not notify the queue set as an existing item + was overwritten in the queue so the number of items + in the queue has not changed. */ + mtCOVERAGE_TEST_MARKER(); + } + else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to + do this from within the critical section - the + kernel takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes + and the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* If there was a task waiting for data to arrive on the + queue then unblock it now. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The unblocked task has a priority higher than + our own so yield immediately. Yes it is ok to do + this from within the critical section - the kernel + takes care of that. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else if( xYieldRequired != pdFALSE ) + { + /* This path is a special case that will only get + executed if the task was holding multiple mutexes and + the mutexes were given back in an order that is + different to that in which they were taken. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was full and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + + /* Return to the original privilege level before exiting + the function. */ + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was full and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_SEND( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait ); + + /* Unlocking the queue means queue events can effect the + event list. It is possible that interrupts occurring now + remove this task from the event list again - but as the + scheduler is suspended the task will go onto the pending + ready last instead of the actual ready list. */ + prvUnlockQueue( pxQueue ); + + /* Resuming the scheduler will move tasks from the pending + ready list into the ready list - so it is feasible that this + task is already in a ready list before it yields - in which + case the yield will not cause a context switch unless there + is also a higher priority task in the pending ready list. */ + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + } + else + { + /* Try again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + traceQUEUE_SEND_FAILED( pxQueue ); + return errQUEUE_FULL; + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + /* Similar to xQueueGenericSend, except without blocking if there is no room + in the queue. Also don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* Semaphores use xQueueGiveFromISR(), so pxQueue will not be a + semaphore or mutex. That means prvCopyDataToQueue() cannot result + in a task disinheriting a priority and prvCopyDataToQueue() can be + called here even though the disinherit function does not check if + the scheduler is suspended before accessing the ready lists. */ + ( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition ); + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting + to the queue set caused a higher priority task to + unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + /* Similar to xQueueGenericSendFromISR() but used with semaphores where the + item size is 0. Don't directly wake a task that was blocked on a queue + read, instead return a flag to say whether a context switch is required or + not (i.e. has a task with a higher priority than us been woken by this + post). */ + + configASSERT( pxQueue ); + + /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() + if the item size is not 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Normally a mutex would not be given from an interrupt, especially if + there is a mutex holder, as priority inheritance makes no sense for an + interrupts, only tasks. */ + configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* When the queue is used to implement a semaphore no data is ever + moved through the queue but it is still valid to see if the queue 'has + space'. */ + if( uxMessagesWaiting < pxQueue->uxLength ) + { + const int8_t cTxLock = pxQueue->cTxLock; + + traceQUEUE_SEND_FROM_ISR( pxQueue ); + + /* A task can only have an inherited priority if it is a mutex + holder - and if there is a mutex holder then the mutex cannot be + given from an ISR. As this is the ISR version of the function it + can be assumed there is no mutex holder and no need to determine if + priority disinheritance is needed. Simply increase the count of + messages (semaphores) available. */ + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + /* The event list is not altered if the queue is locked. This will + be done when the queue is unlocked later. */ + if( cTxLock == queueUNLOCKED ) + { + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The semaphore is a member of a queue set, and + posting to the queue set caused a higher priority + task to unblock. A context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so + record that a context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_QUEUE_SETS */ + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was posted while it was locked. */ + pxQueue->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + traceQUEUE_SEND_FROM_ISR_FAILED( pxQueue ); + xReturn = errQUEUE_FULL; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data available, remove one item. */ + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_RECEIVE( pxQueue ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* There is now space in the queue, were any tasks waiting to + post to the queue? If so, unblock the highest priority waiting + task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* The timeout has not expired. If the queue is still empty place + the task on the list of tasks waiting to receive from the queue. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The queue contains data again. Loop back to try and read the + data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. If there is no data in the queue exit, otherwise loop + back and attempt to read the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +Queue_t * const pxQueue = xQueue; + +#if( configUSE_MUTEXES == 1 ) + BaseType_t xInheritanceOccurred = pdFALSE; +#endif + + /* Check the queue pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* Check this really is a semaphore, in which case the item size will be + 0. */ + configASSERT( pxQueue->uxItemSize == 0 ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to allow return + statements within the function itself. This is done in the interest + of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + /* Semaphores are queues with an item size of 0, and where the + number of messages in the queue is the semaphore's count value. */ + const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxSemaphoreCount > ( UBaseType_t ) 0 ) + { + traceQUEUE_RECEIVE( pxQueue ); + + /* Semaphores are queues with a data size of zero and where the + messages waiting is the semaphore's count. Reduce the count. */ + pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1; + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* Record the information required to implement + priority inheritance should it become necessary. */ + pxQueue->u.xSemaphore.xMutexHolder = pvTaskIncrementMutexHeldCount(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + + /* Check to see if other tasks are blocked waiting to give the + semaphore, and if so, unblock the highest priority such task. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* For inheritance to have occurred there must have been an + initial timeout, and an adjusted timeout cannot become 0, as + if it were 0 the function would have exited. */ + #if( configUSE_MUTEXES == 1 ) + { + configASSERT( xInheritanceOccurred == pdFALSE ); + } + #endif /* configUSE_MUTEXES */ + + /* The semaphore count was 0 and no block time is specified + (or the block time has expired) so exit now. */ + taskEXIT_CRITICAL(); + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The semaphore count was 0 and a block time was specified + so configure the timeout structure ready to block. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can give to and take from the semaphore + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* A block time is specified and not expired. If the semaphore + count is 0 then enter the Blocked state to wait for a semaphore to + become available. As semaphores are implemented with queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); + + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + taskENTER_CRITICAL(); + { + xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif + + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There was no timeout and the semaphore count was not 0, so + attempt to take the semaphore again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* Timed out. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + /* If the semaphore count is 0 exit now as the timeout has + expired. Otherwise return to attempt to take the semaphore that is + known to be available. As semaphores are implemented by queues the + queue being empty is equivalent to the semaphore count being 0. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + #if ( configUSE_MUTEXES == 1 ) + { + /* xInheritanceOccurred could only have be set if + pxQueue->uxQueueType == queueQUEUE_IS_MUTEX so no need to + test the mutex type again to check it is actually a mutex. */ + if( xInheritanceOccurred != pdFALSE ) + { + taskENTER_CRITICAL(); + { + UBaseType_t uxHighestWaitingPriority; + + /* This task blocking on the mutex caused another + task to inherit this task's priority. Now this task + has timed out the priority should be disinherited + again, but only as low as the next highest priority + task that is waiting for the same mutex. */ + uxHighestWaitingPriority = prvGetDisinheritPriorityAfterTimeout( pxQueue ); + vTaskPriorityDisinheritAfterTimeout( pxQueue->u.xSemaphore.xMutexHolder, uxHighestWaitingPriority ); + } + taskEXIT_CRITICAL(); + } + } + #endif /* configUSE_MUTEXES */ + + traceQUEUE_RECEIVE_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) +{ +BaseType_t xEntryTimeSet = pdFALSE; +TimeOut_t xTimeOut; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + /* Check the pointer is not NULL. */ + configASSERT( ( pxQueue ) ); + + /* The buffer into which data is received can only be NULL if the data size + is zero (so no data is copied into the buffer. */ + configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* Cannot block if the scheduler is suspended. */ + #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + { + configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) ); + } + #endif + + + /*lint -save -e904 This function relaxes the coding standard somewhat to + allow return statements within the function itself. This is done in the + interest of execution time efficiency. */ + for( ;; ) + { + taskENTER_CRITICAL(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Is there data in the queue now? To be running the calling task + must be the highest priority task wanting to access the queue. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Remember the read position so it can be reset after the data + is read from the queue as this function is only peeking the + data, not removing it. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + traceQUEUE_PEEK( pxQueue ); + + /* The data is not being removed, so reset the read pointer. */ + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + /* The data is being left in the queue, so see if there are + any other tasks waiting for the data. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than this task. */ + queueYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskEXIT_CRITICAL(); + return pdPASS; + } + else + { + if( xTicksToWait == ( TickType_t ) 0 ) + { + /* The queue was empty and no block time is specified (or + the block time has expired) so leave now. */ + taskEXIT_CRITICAL(); + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else if( xEntryTimeSet == pdFALSE ) + { + /* The queue was empty and a block time was specified so + configure the timeout structure ready to enter the blocked + state. */ + vTaskInternalSetTimeOutState( &xTimeOut ); + xEntryTimeSet = pdTRUE; + } + else + { + /* Entry time was already set. */ + mtCOVERAGE_TEST_MARKER(); + } + } + } + taskEXIT_CRITICAL(); + + /* Interrupts and other tasks can send to and receive from the queue + now the critical section has been exited. */ + + vTaskSuspendAll(); + prvLockQueue( pxQueue ); + + /* Update the timeout state to see if it has expired yet. */ + if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ) + { + /* Timeout has not expired yet, check to see if there is data in the + queue now, and if not enter the Blocked state to wait for data. */ + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); + vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); + prvUnlockQueue( pxQueue ); + if( xTaskResumeAll() == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* There is data in the queue now, so don't enter the blocked + state, instead return to try and obtain the data. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + } + } + else + { + /* The timeout has expired. If there is still no data in the queue + exit, otherwise go back and try to read the data again. */ + prvUnlockQueue( pxQueue ); + ( void ) xTaskResumeAll(); + + if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) + { + traceQUEUE_PEEK_FAILED( pxQueue ); + return errQUEUE_EMPTY; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } /*lint -restore */ +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + /* Cannot block in an ISR, so check there is data available. */ + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + const int8_t cRxLock = pxQueue->cRxLock; + + traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); + + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; + + /* If the queue is locked the event list will not be modified. + Instead update the lock count so the task that unlocks the queue + will know that an ISR has removed data while the queue was + locked. */ + if( cRxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + /* The task waiting has a higher priority than us so + force a context switch. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Increment the lock count so the task that unlocks the queue + knows that data was removed while it was locked. */ + pxQueue->cRxLock = ( int8_t ) ( cRxLock + 1 ); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_RECEIVE_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) +{ +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; +int8_t *pcOriginalReadPosition; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* Cannot block in an ISR, so check there is data available. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + traceQUEUE_PEEK_FROM_ISR( pxQueue ); + + /* Remember the read position so it can be reset as nothing is + actually being removed from the queue. */ + pcOriginalReadPosition = pxQueue->u.xQueue.pcReadFrom; + prvCopyDataFromQueue( pxQueue, pvBuffer ); + pxQueue->u.xQueue.pcReadFrom = pcOriginalReadPosition; + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + traceQUEUE_PEEK_FROM_ISR_FAILED( pxQueue ); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; + + configASSERT( xQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = ( ( Queue_t * ) xQueue )->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + + taskENTER_CRITICAL(); + { + uxReturn = pxQueue->uxLength - pxQueue->uxMessagesWaiting; + } + taskEXIT_CRITICAL(); + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) +{ +UBaseType_t uxReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + uxReturn = pxQueue->uxMessagesWaiting; + + return uxReturn; +} /*lint !e818 Pointer cannot be declared const as xQueue is a typedef not pointer. */ +/*-----------------------------------------------------------*/ + +void vQueueDelete( QueueHandle_t xQueue ) +{ +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + traceQUEUE_DELETE( pxQueue ); + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + vQueueUnregisterQueue( pxQueue ); + } + #endif + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) ) + { + /* The queue can only have been allocated dynamically - free it + again. */ + vPortFree( pxQueue ); + } + #elif( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + { + /* The queue could have been allocated statically or dynamically, so + check before attempting to free the memory. */ + if( pxQueue->ucStaticallyAllocated == ( uint8_t ) pdFALSE ) + { + vPortFree( pxQueue ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #else + { + /* The queue must have been statically allocated, so is not going to be + deleted. Avoid compiler warnings about the unused parameter. */ + ( void ) pxQueue; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) + { + ( ( Queue_t * ) xQueue )->uxQueueNumber = uxQueueNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) + { + return ( ( Queue_t * ) xQueue )->ucQueueType; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if( configUSE_MUTEXES == 1 ) + + static UBaseType_t prvGetDisinheritPriorityAfterTimeout( const Queue_t * const pxQueue ) + { + UBaseType_t uxHighestPriorityOfWaitingTasks; + + /* If a task waiting for a mutex causes the mutex holder to inherit a + priority, but the waiting task times out, then the holder should + disinherit the priority - but only down to the highest priority of any + other tasks that are waiting for the same mutex. For this purpose, + return the priority of the highest priority task that is waiting for the + mutex. */ + if( listCURRENT_LIST_LENGTH( &( pxQueue->xTasksWaitingToReceive ) ) > 0U ) + { + uxHighestPriorityOfWaitingTasks = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) listGET_ITEM_VALUE_OF_HEAD_ENTRY( &( pxQueue->xTasksWaitingToReceive ) ); + } + else + { + uxHighestPriorityOfWaitingTasks = tskIDLE_PRIORITY; + } + + return uxHighestPriorityOfWaitingTasks; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvCopyDataToQueue( Queue_t * const pxQueue, const void *pvItemToQueue, const BaseType_t xPosition ) +{ +BaseType_t xReturn = pdFALSE; +UBaseType_t uxMessagesWaiting; + + /* This function is called from a critical section. */ + + uxMessagesWaiting = pxQueue->uxMessagesWaiting; + + if( pxQueue->uxItemSize == ( UBaseType_t ) 0 ) + { + #if ( configUSE_MUTEXES == 1 ) + { + if( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) + { + /* The mutex is no longer being held. */ + xReturn = xTaskPriorityDisinherit( pxQueue->u.xSemaphore.xMutexHolder ); + pxQueue->u.xSemaphore.xMutexHolder = NULL; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_MUTEXES */ + } + else if( xPosition == queueSEND_TO_BACK ) + { + ( void ) memcpy( ( void * ) pxQueue->pcWriteTo, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports, plus previous logic ensures a null pointer can only be passed to memcpy() if the copy size is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + pxQueue->pcWriteTo += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->pcWriteTo >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->pcWriteTo = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + ( void ) memcpy( ( void * ) pxQueue->u.xQueue.pcReadFrom, pvItemToQueue, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e9087 !e418 MISRA exception as the casts are only redundant for some ports. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. Assert checks null pointer only used when length is 0. */ + pxQueue->u.xQueue.pcReadFrom -= pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom < pxQueue->pcHead ) /*lint !e946 MISRA exception justified as comparison of pointers is the cleanest solution. */ + { + pxQueue->u.xQueue.pcReadFrom = ( pxQueue->u.xQueue.pcTail - pxQueue->uxItemSize ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xPosition == queueOVERWRITE ) + { + if( uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* An item is not being added but overwritten, so subtract + one from the recorded number of items in the queue so when + one is added again below the number of recorded items remains + correct. */ + --uxMessagesWaiting; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxQueue->uxMessagesWaiting = uxMessagesWaiting + ( UBaseType_t ) 1; + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer ) +{ + if( pxQueue->uxItemSize != ( UBaseType_t ) 0 ) + { + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; /*lint !e9016 Pointer arithmetic on char types ok, especially in this use case where it is the clearest way of conveying intent. */ + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) /*lint !e946 MISRA exception justified as use of the relational operator is the cleanest solutions. */ + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 !e9087 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. Cast to void required by function signature and safe as no alignment requirement and copy length specified in bytes. */ + } +} +/*-----------------------------------------------------------*/ + +static void prvUnlockQueue( Queue_t * const pxQueue ) +{ + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */ + + /* The lock counts contains the number of extra data items placed or + removed from the queue while the queue was locked. When a queue is + locked items can be added or removed, but the event lists cannot be + updated. */ + taskENTER_CRITICAL(); + { + int8_t cTxLock = pxQueue->cTxLock; + + /* See if data was added to the queue while it was locked. */ + while( cTxLock > queueLOCKED_UNMODIFIED ) + { + /* Data was posted while the queue was locked. Are any tasks + blocked waiting for data to become available? */ + #if ( configUSE_QUEUE_SETS == 1 ) + { + if( pxQueue->pxQueueSetContainer != NULL ) + { + if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) != pdFALSE ) + { + /* The queue is a member of a queue set, and posting to + the queue set caused a higher priority task to unblock. + A context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* Tasks that are removed from the event list will get + added to the pending ready list as the scheduler is still + suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that a + context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + } + #else /* configUSE_QUEUE_SETS */ + { + /* Tasks that are removed from the event list will get added to + the pending ready list as the scheduler is still suspended. */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority so record that + a context switch is required. */ + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + break; + } + } + #endif /* configUSE_QUEUE_SETS */ + + --cTxLock; + } + + pxQueue->cTxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); + + /* Do the same for the Rx lock. */ + taskENTER_CRITICAL(); + { + int8_t cRxLock = pxQueue->cRxLock; + + while( cRxLock > queueLOCKED_UNMODIFIED ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + vTaskMissedYield(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + --cRxLock; + } + else + { + break; + } + } + + pxQueue->cRxLock = queueUNLOCKED; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueEmpty( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +static BaseType_t prvIsQueueFull( const Queue_t *pxQueue ) +{ +BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) +{ +BaseType_t xReturn; +Queue_t * const pxQueue = xQueue; + + configASSERT( pxQueue ); + if( pxQueue->uxMessagesWaiting == pxQueue->uxLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already full we may have to block. A critical section + is required to prevent an interrupt removing something from the queue + between the check to see if the queue is full and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( prvIsQueueFull( pxQueue ) != pdFALSE ) + { + /* The queue is full - do we want to block or just leave without + posting? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is called from a coroutine we cannot block directly, but + return indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + /* There is room in the queue, copy the data into the queue. */ + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + xReturn = pdPASS; + + /* Were any co-routines waiting for data to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The co-routine waiting has a higher priority so record + that a yield might be appropriate. */ + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = errQUEUE_FULL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* If the queue is already empty we may have to block. A critical section + is required to prevent an interrupt adding something to the queue + between the check to see if the queue is empty and blocking on the queue. */ + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0 ) + { + /* There are no messages in the queue, do we want to block or just + leave with nothing? */ + if( xTicksToWait > ( TickType_t ) 0 ) + { + /* As this is a co-routine we cannot block directly, but return + indicating that we need to block. */ + vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToReceive ) ); + portENABLE_INTERRUPTS(); + return errQUEUE_BLOCKED; + } + else + { + portENABLE_INTERRUPTS(); + return errQUEUE_FULL; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portENABLE_INTERRUPTS(); + + portDISABLE_INTERRUPTS(); + { + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Data is available from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + xReturn = pdPASS; + + /* Were any co-routines waiting for space to become available? */ + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + /* In this instance the co-routine could be placed directly + into the ready list as we are within a critical section. + Instead the same pending ready list mechanism is used as if + the event were caused from within an interrupt. */ + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + xReturn = errQUEUE_YIELD; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xReturn = pdFAIL; + } + } + portENABLE_INTERRUPTS(); + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ) + { + Queue_t * const pxQueue = xQueue; + + /* Cannot block within an ISR so if there is no space on the queue then + exit without doing anything. */ + if( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) + { + prvCopyDataToQueue( pxQueue, pvItemToQueue, queueSEND_TO_BACK ); + + /* We only want to wake one co-routine per ISR, so check that a + co-routine has not already been woken. */ + if( xCoRoutinePreviouslyWoken == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE ) + { + return pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCoRoutinePreviouslyWoken; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_CO_ROUTINES == 1 ) + + BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxCoRoutineWoken ) + { + BaseType_t xReturn; + Queue_t * const pxQueue = xQueue; + + /* We cannot block from an ISR, so check there is data available. If + not then just leave without doing anything. */ + if( pxQueue->uxMessagesWaiting > ( UBaseType_t ) 0 ) + { + /* Copy the data from the queue. */ + pxQueue->u.xQueue.pcReadFrom += pxQueue->uxItemSize; + if( pxQueue->u.xQueue.pcReadFrom >= pxQueue->u.xQueue.pcTail ) + { + pxQueue->u.xQueue.pcReadFrom = pxQueue->pcHead; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --( pxQueue->uxMessagesWaiting ); + ( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.xQueue.pcReadFrom, ( unsigned ) pxQueue->uxItemSize ); + + if( ( *pxCoRoutineWoken ) == pdFALSE ) + { + if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) + { + if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) + { + *pxCoRoutineWoken = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_CO_ROUTINES */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + + /* See if there is an empty space in the registry. A NULL name denotes + a free slot. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].pcQueueName == NULL ) + { + /* Store the information on this queue. */ + xQueueRegistry[ ux ].pcQueueName = pcQueueName; + xQueueRegistry[ ux ].xHandle = xQueue; + + traceQUEUE_REGISTRY_ADD( xQueue, pcQueueName ); + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + const char *pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t ux; + const char *pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + /* Note there is nothing here to protect against another task adding or + removing entries from the registry while it is being searched. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + pcReturn = xQueueRegistry[ ux ].pcQueueName; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return pcReturn; + } /*lint !e818 xQueue cannot be a pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configQUEUE_REGISTRY_SIZE > 0 ) + + void vQueueUnregisterQueue( QueueHandle_t xQueue ) + { + UBaseType_t ux; + + /* See if the handle of the queue being unregistered in actually in the + registry. */ + for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ ) + { + if( xQueueRegistry[ ux ].xHandle == xQueue ) + { + /* Set the name to NULL to show that this slot if free again. */ + xQueueRegistry[ ux ].pcQueueName = NULL; + + /* Set the handle to NULL to ensure the same queue handle cannot + appear in the registry twice if it is added, removed, then + added again. */ + xQueueRegistry[ ux ].xHandle = ( QueueHandle_t ) 0; + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + } /*lint !e818 xQueue could not be pointer to const because it is a typedef. */ + +#endif /* configQUEUE_REGISTRY_SIZE */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TIMERS == 1 ) + + void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + Queue_t * const pxQueue = xQueue; + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements. + It can result in vListInsert() being called on a list that can only + possibly ever have one item in it, so the list will be fast, but even + so it should be called with the scheduler locked and not from a critical + section. */ + + /* Only do anything if there are no messages in the queue. This function + will not actually cause the task to block, just place it on a blocked + list. It will not block until the scheduler is unlocked - at which + time a yield will be performed. If an item is added to the queue while + the queue is locked, and the calling task blocks on the queue, then the + calling task will be immediately unblocked when the queue is unlocked. */ + prvLockQueue( pxQueue ); + if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U ) + { + /* There is nothing in the queue, block for the specified period. */ + vTaskPlaceOnEventListRestricted( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait, xWaitIndefinitely ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + prvUnlockQueue( pxQueue ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +#if( ( configUSE_QUEUE_SETS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) + { + QueueSetHandle_t pxQueue; + + pxQueue = xQueueGenericCreate( uxEventQueueLength, ( UBaseType_t ) sizeof( Queue_t * ), queueQUEUE_TYPE_SET ); + + return pxQueue; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + if( ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer != NULL ) + { + /* Cannot add a queue/semaphore to more than one queue set. */ + xReturn = pdFAIL; + } + else if( ( ( Queue_t * ) xQueueOrSemaphore )->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* Cannot add a queue/semaphore to a queue set if there are already + items in the queue/semaphore. */ + xReturn = pdFAIL; + } + else + { + ( ( Queue_t * ) xQueueOrSemaphore )->pxQueueSetContainer = xQueueSet; + xReturn = pdPASS; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) + { + BaseType_t xReturn; + Queue_t * const pxQueueOrSemaphore = ( Queue_t * ) xQueueOrSemaphore; + + if( pxQueueOrSemaphore->pxQueueSetContainer != xQueueSet ) + { + /* The queue was not a member of the set. */ + xReturn = pdFAIL; + } + else if( pxQueueOrSemaphore->uxMessagesWaiting != ( UBaseType_t ) 0 ) + { + /* It is dangerous to remove a queue from a set when the queue is + not empty because the queue set will still hold pending events for + the queue. */ + xReturn = pdFAIL; + } + else + { + taskENTER_CRITICAL(); + { + /* The queue is no longer contained in the set. */ + pxQueueOrSemaphore->pxQueueSetContainer = NULL; + } + taskEXIT_CRITICAL(); + xReturn = pdPASS; + } + + return xReturn; + } /*lint !e818 xQueueSet could not be declared as pointing to const as it is a typedef. */ + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, TickType_t const xTicksToWait ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceive( ( QueueHandle_t ) xQueueSet, &xReturn, xTicksToWait ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) + { + QueueSetMemberHandle_t xReturn = NULL; + + ( void ) xQueueReceiveFromISR( ( QueueHandle_t ) xQueueSet, &xReturn, NULL ); /*lint !e961 Casting from one typedef to another is not redundant. */ + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_QUEUE_SETS == 1 ) + + static BaseType_t prvNotifyQueueSetContainer( const Queue_t * const pxQueue, const BaseType_t xCopyPosition ) + { + Queue_t *pxQueueSetContainer = pxQueue->pxQueueSetContainer; + BaseType_t xReturn = pdFALSE; + + /* This function must be called form a critical section. */ + + configASSERT( pxQueueSetContainer ); + configASSERT( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ); + + if( pxQueueSetContainer->uxMessagesWaiting < pxQueueSetContainer->uxLength ) + { + const int8_t cTxLock = pxQueueSetContainer->cTxLock; + + traceQUEUE_SEND( pxQueueSetContainer ); + + /* The data copied is the handle of the queue that contains data. */ + xReturn = prvCopyDataToQueue( pxQueueSetContainer, &pxQueue, xCopyPosition ); + + if( cTxLock == queueUNLOCKED ) + { + if( listLIST_IS_EMPTY( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) == pdFALSE ) + { + if( xTaskRemoveFromEventList( &( pxQueueSetContainer->xTasksWaitingToReceive ) ) != pdFALSE ) + { + /* The task waiting has a higher priority. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxQueueSetContainer->cTxLock = ( int8_t ) ( cTxLock + 1 ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_QUEUE_SETS */ + +/*-----------------------------------------------------------*/ +void vQueueEndScheduler(void) { /* << EST */ +#if configQUEUE_REGISTRY_SIZE>0 + memset(xQueueRegistry, 0, sizeof(xQueueRegistry)); +#endif /* configQUEUE_REGISTRY_SIZE */ +} + + + + + + + + + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.h new file mode 100644 index 0000000..dc48ef7 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/queue.h @@ -0,0 +1,1657 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef QUEUE_H +#define QUEUE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include queue.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include "task.h" + +/** + * Type by which queues are referenced. For example, a call to xQueueCreate() + * returns an QueueHandle_t variable that can then be used as a parameter to + * xQueueSend(), xQueueReceive(), etc. + */ +struct QueueDefinition; /* Using old naming convention so as not to break kernel aware debuggers. */ +typedef struct QueueDefinition * QueueHandle_t; + +/** + * Type by which queue sets are referenced. For example, a call to + * xQueueCreateSet() returns an xQueueSet variable that can then be used as a + * parameter to xQueueSelectFromSet(), xQueueAddToSet(), etc. + */ +typedef struct QueueDefinition * QueueSetHandle_t; + +/** + * Queue sets can contain both queues and semaphores, so the + * QueueSetMemberHandle_t is defined as a type to be used where a parameter or + * return value can be either an QueueHandle_t or an SemaphoreHandle_t. + */ +typedef struct QueueDefinition * QueueSetMemberHandle_t; + +/* For internal use only. */ +#define queueSEND_TO_BACK ( ( BaseType_t ) 0 ) +#define queueSEND_TO_FRONT ( ( BaseType_t ) 1 ) +#define queueOVERWRITE ( ( BaseType_t ) 2 ) + +/* For internal use only. These definitions *must* match those in queue.c. */ +#define queueQUEUE_TYPE_BASE ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_SET ( ( uint8_t ) 0U ) +#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U ) +#define queueQUEUE_TYPE_COUNTING_SEMAPHORE ( ( uint8_t ) 2U ) +#define queueQUEUE_TYPE_BINARY_SEMAPHORE ( ( uint8_t ) 3U ) +#define queueQUEUE_TYPE_RECURSIVE_MUTEX ( ( uint8_t ) 4U ) + +/** + * queue. h + *
+ QueueHandle_t xQueueCreate(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @return If the queue is successfully create then a handle to the newly + * created queue is returned. If the queue cannot be created then 0 is + * returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+	if( xQueue1 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue2 == 0 )
+	{
+		// Queue was not created and must not be used.
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreate xQueueCreate + * \ingroup QueueManagement + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xQueueCreate( uxQueueLength, uxItemSize ) xQueueGenericCreate( ( uxQueueLength ), ( uxItemSize ), ( queueQUEUE_TYPE_BASE ) ) +#endif + +/** + * queue. h + *
+ QueueHandle_t xQueueCreateStatic(
+							  UBaseType_t uxQueueLength,
+							  UBaseType_t uxItemSize,
+							  uint8_t *pucQueueStorageBuffer,
+							  StaticQueue_t *pxQueueBuffer
+						  );
+ * 
+ * + * Creates a new queue instance, and returns a handle by which the new queue + * can be referenced. + * + * Internally, within the FreeRTOS implementation, queues use two blocks of + * memory. The first block is used to hold the queue's data structures. The + * second block is used to hold items placed into the queue. If a queue is + * created using xQueueCreate() then both blocks of memory are automatically + * dynamically allocated inside the xQueueCreate() function. (see + * http://www.freertos.org/a00111.html). If a queue is created using + * xQueueCreateStatic() then the application writer must provide the memory that + * will get used by the queue. xQueueCreateStatic() therefore allows a queue to + * be created without using any dynamic memory allocation. + * + * http://www.FreeRTOS.org/Embedded-RTOS-Queues.html + * + * @param uxQueueLength The maximum number of items that the queue can contain. + * + * @param uxItemSize The number of bytes each item in the queue will require. + * Items are queued by copy, not by reference, so this is the number of bytes + * that will be copied for each posted item. Each item on the queue must be + * the same size. + * + * @param pucQueueStorageBuffer If uxItemSize is not zero then + * pucQueueStorageBuffer must point to a uint8_t array that is at least large + * enough to hold the maximum number of items that can be in the queue at any + * one time - which is ( uxQueueLength * uxItemsSize ) bytes. If uxItemSize is + * zero then pucQueueStorageBuffer can be NULL. + * + * @param pxQueueBuffer Must point to a variable of type StaticQueue_t, which + * will be used to hold the queue's data structure. + * + * @return If the queue is created then a handle to the created queue is + * returned. If pxQueueBuffer is NULL then NULL is returned. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ };
+
+ #define QUEUE_LENGTH 10
+ #define ITEM_SIZE sizeof( uint32_t )
+
+ // xQueueBuffer will hold the queue structure.
+ StaticQueue_t xQueueBuffer;
+
+ // ucQueueStorage will hold the items posted to the queue.  Must be at least
+ // [(queue length) * ( queue item size)] bytes long.
+ uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( QUEUE_LENGTH, // The number of items the queue can hold.
+							ITEM_SIZE	  // The size of each item in the queue
+							&( ucQueueStorage[ 0 ] ), // The buffer that will hold the items in the queue.
+							&xQueueBuffer ); // The buffer that will hold the queue structure.
+
+	// The queue is guaranteed to be created successfully as no dynamic memory
+	// allocation is used.  Therefore xQueue1 is now a handle to a valid queue.
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueCreateStatic xQueueCreateStatic + * \ingroup QueueManagement + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xQueueCreateStatic( uxQueueLength, uxItemSize, pucQueueStorage, pxQueueBuffer ) xQueueGenericCreateStatic( ( uxQueueLength ), ( uxItemSize ), ( pucQueueStorage ), ( pxQueueBuffer ), ( queueQUEUE_TYPE_BASE ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * queue. h + *
+ BaseType_t xQueueSendToToFront(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * Post an item to the front of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToFront( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToFront( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToFront( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_FRONT ) + +/** + * queue. h + *
+ BaseType_t xQueueSendToBack(
+								   QueueHandle_t	xQueue,
+								   const void		*pvItemToQueue,
+								   TickType_t		xTicksToWait
+							   );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). + * + * Post an item to the back of a queue. The item is queued by copy, not by + * reference. This function must not be called from an interrupt service + * routine. See xQueueSendFromISR () for an alternative which may be used + * in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the queue + * is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSendToBack( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSendToBack( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSendToBack( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueSend(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  TickType_t xTicksToWait
+						 );
+ * 
+ * + * This is a macro that calls xQueueGenericSend(). It is included for + * backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToFront() and xQueueSendToBack() macros. It is + * equivalent to xQueueSendToBack(). + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10 ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0 );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +#define xQueueSend( xQueue, pvItemToQueue, xTicksToWait ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), ( xTicksToWait ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwrite(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue
+						 );
+ * 
+ * + * Only for use with queues that have a length of one - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * This function must not be called from an interrupt service routine. + * See xQueueOverwriteFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle of the queue to which the data is being sent. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @return xQueueOverwrite() is a macro that calls xQueueGenericSend(), and + * therefore has the same return values as xQueueSendToFront(). However, pdPASS + * is the only value that can be returned because xQueueOverwrite() will write + * to the queue even when the queue is already full. + * + * Example usage: +
+
+ void vFunction( void *pvParameters )
+ {
+ QueueHandle_t xQueue;
+ uint32_t ulVarToSend, ulValReceived;
+
+	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwrite() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+
+	// Write the value 10 to the queue using xQueueOverwrite().
+	ulVarToSend = 10;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// Peeking the queue should now return 10, but leave the value 10 in
+	// the queue.  A block time of zero is used as it is known that the
+	// queue holds a value.
+	ulValReceived = 0;
+	xQueuePeek( xQueue, &ulValReceived, 0 );
+
+	if( ulValReceived != 10 )
+	{
+		// Error unless the item was removed by a different task.
+	}
+
+	// The queue is still full.  Use xQueueOverwrite() to overwrite the
+	// value held in the queue with 100.
+	ulVarToSend = 100;
+	xQueueOverwrite( xQueue, &ulVarToSend );
+
+	// This time read from the queue, leaving the queue empty once more.
+	// A block time of 0 is used again.
+	xQueueReceive( xQueue, &ulValReceived, 0 );
+
+	// The value read should be the last value written, even though the
+	// queue was already full when the value was written.
+	if( ulValReceived != 100 )
+	{
+		// Error!
+	}
+
+	// ...
+}
+ 
+ * \defgroup xQueueOverwrite xQueueOverwrite + * \ingroup QueueManagement + */ +#define xQueueOverwrite( xQueue, pvItemToQueue ) xQueueGenericSend( ( xQueue ), ( pvItemToQueue ), 0, queueOVERWRITE ) + + +/** + * queue. h + *
+ BaseType_t xQueueGenericSend(
+									QueueHandle_t xQueue,
+									const void * pvItemToQueue,
+									TickType_t xTicksToWait
+									BaseType_t xCopyPosition
+								);
+ * 
+ * + * It is preferred that the macros xQueueSend(), xQueueSendToFront() and + * xQueueSendToBack() are used in place of calling this function directly. + * + * Post an item on a queue. The item is queued by copy, not by reference. + * This function must not be called from an interrupt service routine. + * See xQueueSendFromISR () for an alternative which may be used in an ISR. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for space to become available on the queue, should it already + * be full. The call will return immediately if this is set to 0 and the + * queue is full. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the item was successfully posted, otherwise errQUEUE_FULL. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ uint32_t ulVar = 10UL;
+
+ void vATask( void *pvParameters )
+ {
+ QueueHandle_t xQueue1, xQueue2;
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 uint32_t values.
+	xQueue1 = xQueueCreate( 10, sizeof( uint32_t ) );
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue2 = xQueueCreate( 10, sizeof( struct AMessage * ) );
+
+	// ...
+
+	if( xQueue1 != 0 )
+	{
+		// Send an uint32_t.  Wait for 10 ticks for space to become
+		// available if necessary.
+		if( xQueueGenericSend( xQueue1, ( void * ) &ulVar, ( TickType_t ) 10, queueSEND_TO_BACK ) != pdPASS )
+		{
+			// Failed to post the message, even after 10 ticks.
+		}
+	}
+
+	if( xQueue2 != 0 )
+	{
+		// Send a pointer to a struct AMessage object.  Don't block if the
+		// queue is already full.
+		pxMessage = & xMessage;
+		xQueueGenericSend( xQueue2, ( void * ) &pxMessage, ( TickType_t ) 0, queueSEND_TO_BACK );
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueSend xQueueSend + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeek(
+							 QueueHandle_t xQueue,
+							 void * const pvBuffer,
+							 TickType_t xTicksToWait
+						 );
+ * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * This macro must not be used in an interrupt service routine. See + * xQueuePeekFromISR() for an alternative that can be called from an interrupt + * service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. The time is defined in tick periods so the constant + * portTICK_PERIOD_MS should be used to convert to real time if this is required. + * xQueuePeek() will return immediately if xTicksToWait is 0 and the queue + * is empty. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to peek the data from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Peek a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueuePeek( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask, but the item still remains on the queue.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueuePeek xQueuePeek + * \ingroup QueueManagement + */ +BaseType_t xQueuePeek( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueuePeekFromISR(
+									QueueHandle_t xQueue,
+									void *pvBuffer,
+								);
+ * + * A version of xQueuePeek() that can be called from an interrupt service + * routine (ISR). + * + * Receive an item from a queue without removing the item from the queue. + * The item is received by copy so a buffer of adequate size must be + * provided. The number of bytes copied into the buffer was defined when + * the queue was created. + * + * Successfully received items remain on the queue so will be returned again + * by the next call, or a call to xQueueReceive(). + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * \defgroup xQueuePeekFromISR xQueuePeekFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, void * const pvBuffer ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceive(
+								 QueueHandle_t xQueue,
+								 void *pvBuffer,
+								 TickType_t xTicksToWait
+							);
+ * + * Receive an item from a queue. The item is received by copy so a buffer of + * adequate size must be provided. The number of bytes copied into the buffer + * was defined when the queue was created. + * + * Successfully received items are removed from the queue. + * + * This function must not be used in an interrupt service routine. See + * xQueueReceiveFromISR for an alternative that can. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param xTicksToWait The maximum amount of time the task should block + * waiting for an item to receive should the queue be empty at the time + * of the call. xQueueReceive() will return immediately if xTicksToWait + * is zero and the queue is empty. The time is defined in tick periods so the + * constant portTICK_PERIOD_MS should be used to convert to real time if this is + * required. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+ struct AMessage
+ {
+	char ucMessageID;
+	char ucData[ 20 ];
+ } xMessage;
+
+ QueueHandle_t xQueue;
+
+ // Task to create a queue and post a value.
+ void vATask( void *pvParameters )
+ {
+ struct AMessage *pxMessage;
+
+	// Create a queue capable of containing 10 pointers to AMessage structures.
+	// These should be passed by pointer as they contain a lot of data.
+	xQueue = xQueueCreate( 10, sizeof( struct AMessage * ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Send a pointer to a struct AMessage object.  Don't block if the
+	// queue is already full.
+	pxMessage = & xMessage;
+	xQueueSend( xQueue, ( void * ) &pxMessage, ( TickType_t ) 0 );
+
+	// ... Rest of task code.
+ }
+
+ // Task to receive from the queue.
+ void vADifferentTask( void *pvParameters )
+ {
+ struct AMessage *pxRxedMessage;
+
+	if( xQueue != 0 )
+	{
+		// Receive a message on the created queue.  Block for 10 ticks if a
+		// message is not immediately available.
+		if( xQueueReceive( xQueue, &( pxRxedMessage ), ( TickType_t ) 10 ) )
+		{
+			// pcRxedMessage now points to the struct AMessage variable posted
+			// by vATask.
+		}
+	}
+
+	// ... Rest of task code.
+ }
+ 
+ * \defgroup xQueueReceive xQueueReceive + * \ingroup QueueManagement + */ +BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue );
+ * + * Return the number of messages stored in a queue. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of messages available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueMessagesWaiting( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue );
+ * + * Return the number of free spaces available in a queue. This is equal to the + * number of items that can be sent to the queue before the queue becomes full + * if no items are removed. + * + * @param xQueue A handle to the queue being queried. + * + * @return The number of spaces available in the queue. + * + * \defgroup uxQueueMessagesWaiting uxQueueMessagesWaiting + * \ingroup QueueManagement + */ +UBaseType_t uxQueueSpacesAvailable( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
void vQueueDelete( QueueHandle_t xQueue );
+ * + * Delete a queue - freeing all the memory allocated for storing of items + * placed on the queue. + * + * @param xQueue A handle to the queue to be deleted. + * + * \defgroup vQueueDelete vQueueDelete + * \ingroup QueueManagement + */ +void vQueueDelete( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueSendToFrontFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the front of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToFrontFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToFromFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPrioritTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToFrontFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_FRONT ) + + +/** + * queue. h + *
+ BaseType_t xQueueSendToBackFromISR(
+										 QueueHandle_t xQueue,
+										 const void *pvItemToQueue,
+										 BaseType_t *pxHigherPriorityTaskWoken
+									  );
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). + * + * Post an item to the back of a queue. It is safe to use this macro from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendToBackFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendToBackFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendToBackFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendToBackFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueOverwriteFromISR(
+							  QueueHandle_t xQueue,
+							  const void * pvItemToQueue,
+							  BaseType_t *pxHigherPriorityTaskWoken
+						 );
+ * 
+ * + * A version of xQueueOverwrite() that can be used in an interrupt service + * routine (ISR). + * + * Only for use with queues that can hold a single item - so the queue is either + * empty or full. + * + * Post an item on a queue. If the queue is already full then overwrite the + * value held in the queue. The item is queued by copy, not by reference. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueOverwriteFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueOverwriteFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return xQueueOverwriteFromISR() is a macro that calls + * xQueueGenericSendFromISR(), and therefore has the same return values as + * xQueueSendToFrontFromISR(). However, pdPASS is the only value that can be + * returned because xQueueOverwriteFromISR() will write to the queue even when + * the queue is already full. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ void vFunction( void *pvParameters )
+ {
+ 	// Create a queue to hold one uint32_t value.  It is strongly
+	// recommended *not* to use xQueueOverwriteFromISR() on queues that can
+	// contain more than one value, and doing so will trigger an assertion
+	// if configASSERT() is defined.
+	xQueue = xQueueCreate( 1, sizeof( uint32_t ) );
+}
+
+void vAnInterruptHandler( void )
+{
+// xHigherPriorityTaskWoken must be set to pdFALSE before it is used.
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulVarToSend, ulValReceived;
+
+	// Write the value 10 to the queue using xQueueOverwriteFromISR().
+	ulVarToSend = 10;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// The queue is full, but calling xQueueOverwriteFromISR() again will still
+	// pass because the value held in the queue will be overwritten with the
+	// new value.
+	ulVarToSend = 100;
+	xQueueOverwriteFromISR( xQueue, &ulVarToSend, &xHigherPriorityTaskWoken );
+
+	// Reading from the queue will now return 100.
+
+	// ...
+
+	if( xHigherPrioritytaskWoken == pdTRUE )
+	{
+		// Writing to the queue caused a task to unblock and the unblocked task
+		// has a priority higher than or equal to the priority of the currently
+		// executing task (the task this interrupt interrupted).  Perform a context
+		// switch so this interrupt returns directly to the unblocked task.
+		portYIELD_FROM_ISR(); // or portEND_SWITCHING_ISR() depending on the port.
+	}
+}
+ 
+ * \defgroup xQueueOverwriteFromISR xQueueOverwriteFromISR + * \ingroup QueueManagement + */ +#define xQueueOverwriteFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueOVERWRITE ) + +/** + * queue. h + *
+ BaseType_t xQueueSendFromISR(
+									 QueueHandle_t xQueue,
+									 const void *pvItemToQueue,
+									 BaseType_t *pxHigherPriorityTaskWoken
+								);
+ 
+ * + * This is a macro that calls xQueueGenericSendFromISR(). It is included + * for backward compatibility with versions of FreeRTOS.org that did not + * include the xQueueSendToBackFromISR() and xQueueSendToFrontFromISR() + * macros. + * + * Post an item to the back of a queue. It is safe to use this function from + * within an interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWoken;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWoken = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post the byte.
+		xQueueSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.
+	if( xHigherPriorityTaskWoken )
+	{
+		// Actual macro used here is port specific.
+		portYIELD_FROM_ISR ();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +#define xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken ) xQueueGenericSendFromISR( ( xQueue ), ( pvItemToQueue ), ( pxHigherPriorityTaskWoken ), queueSEND_TO_BACK ) + +/** + * queue. h + *
+ BaseType_t xQueueGenericSendFromISR(
+										   QueueHandle_t		xQueue,
+										   const	void	*pvItemToQueue,
+										   BaseType_t	*pxHigherPriorityTaskWoken,
+										   BaseType_t	xCopyPosition
+									   );
+ 
+ * + * It is preferred that the macros xQueueSendFromISR(), + * xQueueSendToFrontFromISR() and xQueueSendToBackFromISR() be used in place + * of calling this function directly. xQueueGiveFromISR() is an + * equivalent for use by semaphores that don't actually copy any data. + * + * Post an item on a queue. It is safe to use this function from within an + * interrupt service routine. + * + * Items are queued by copy not reference so it is preferable to only + * queue small items, especially when called from an ISR. In most cases + * it would be preferable to store a pointer to the item being queued. + * + * @param xQueue The handle to the queue on which the item is to be posted. + * + * @param pvItemToQueue A pointer to the item that is to be placed on the + * queue. The size of the items the queue will hold was defined when the + * queue was created, so this many bytes will be copied from pvItemToQueue + * into the queue storage area. + * + * @param pxHigherPriorityTaskWoken xQueueGenericSendFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending to the queue caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xQueueGenericSendFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @param xCopyPosition Can take the value queueSEND_TO_BACK to place the + * item at the back of the queue, or queueSEND_TO_FRONT to place the item + * at the front of the queue (for high priority messages). + * + * @return pdTRUE if the data was successfully sent to the queue, otherwise + * errQUEUE_FULL. + * + * Example usage for buffered IO (where the ISR can obtain more than one value + * per call): +
+ void vBufferISR( void )
+ {
+ char cIn;
+ BaseType_t xHigherPriorityTaskWokenByPost;
+
+	// We have not woken a task at the start of the ISR.
+	xHigherPriorityTaskWokenByPost = pdFALSE;
+
+	// Loop until the buffer is empty.
+	do
+	{
+		// Obtain a byte from the buffer.
+		cIn = portINPUT_BYTE( RX_REGISTER_ADDRESS );
+
+		// Post each byte.
+		xQueueGenericSendFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWokenByPost, queueSEND_TO_BACK );
+
+	} while( portINPUT_BYTE( BUFFER_COUNT ) );
+
+	// Now the buffer is empty we can switch context if necessary.  Note that the
+	// name of the yield function required is port specific.
+	if( xHigherPriorityTaskWokenByPost )
+	{
+		taskYIELD_YIELD_FROM_ISR();
+	}
+ }
+ 
+ * + * \defgroup xQueueSendFromISR xQueueSendFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, const void * const pvItemToQueue, BaseType_t * const pxHigherPriorityTaskWoken, const BaseType_t xCopyPosition ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * queue. h + *
+ BaseType_t xQueueReceiveFromISR(
+									   QueueHandle_t	xQueue,
+									   void	*pvBuffer,
+									   BaseType_t *pxTaskWoken
+								   );
+ * 
+ * + * Receive an item from a queue. It is safe to use this function from within an + * interrupt service routine. + * + * @param xQueue The handle to the queue from which the item is to be + * received. + * + * @param pvBuffer Pointer to the buffer into which the received item will + * be copied. + * + * @param pxTaskWoken A task may be blocked waiting for space to become + * available on the queue. If xQueueReceiveFromISR causes such a task to + * unblock *pxTaskWoken will get set to pdTRUE, otherwise *pxTaskWoken will + * remain unchanged. + * + * @return pdTRUE if an item was successfully received from the queue, + * otherwise pdFALSE. + * + * Example usage: +
+
+ QueueHandle_t xQueue;
+
+ // Function to create a queue and post some values.
+ void vAFunction( void *pvParameters )
+ {
+ char cValueToPost;
+ const TickType_t xTicksToWait = ( TickType_t )0xff;
+
+	// Create a queue capable of containing 10 characters.
+	xQueue = xQueueCreate( 10, sizeof( char ) );
+	if( xQueue == 0 )
+	{
+		// Failed to create the queue.
+	}
+
+	// ...
+
+	// Post some characters that will be used within an ISR.  If the queue
+	// is full then this task will block for xTicksToWait ticks.
+	cValueToPost = 'a';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+	cValueToPost = 'b';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+
+	// ... keep posting characters ... this task may block when the queue
+	// becomes full.
+
+	cValueToPost = 'c';
+	xQueueSend( xQueue, ( void * ) &cValueToPost, xTicksToWait );
+ }
+
+ // ISR that outputs all the characters received on the queue.
+ void vISR_Routine( void )
+ {
+ BaseType_t xTaskWokenByReceive = pdFALSE;
+ char cRxedChar;
+
+	while( xQueueReceiveFromISR( xQueue, ( void * ) &cRxedChar, &xTaskWokenByReceive) )
+	{
+		// A character was received.  Output the character now.
+		vOutputCharacter( cRxedChar );
+
+		// If removing the character from the queue woke the task that was
+		// posting onto the queue cTaskWokenByReceive will have been set to
+		// pdTRUE.  No matter how many times this loop iterates only one
+		// task will be woken.
+	}
+
+	if( cTaskWokenByPost != ( char ) pdFALSE;
+	{
+		taskYIELD ();
+	}
+ }
+ 
+ * \defgroup xQueueReceiveFromISR xQueueReceiveFromISR + * \ingroup QueueManagement + */ +BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, void * const pvBuffer, BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* + * Utilities to query queues that are safe to use from an ISR. These utilities + * should be used only from witin an ISR, or within a critical section. + */ +BaseType_t xQueueIsQueueEmptyFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueIsQueueFullFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueMessagesWaitingFromISR( const QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +/* + * The functions defined above are for passing data to and from tasks. The + * functions below are the equivalents for passing data to and from + * co-routines. + * + * These functions are called from the co-routine macro implementation and + * should not be called directly from application code. Instead use the macro + * wrappers defined within croutine.h. + */ +BaseType_t xQueueCRSendFromISR( QueueHandle_t xQueue, const void *pvItemToQueue, BaseType_t xCoRoutinePreviouslyWoken ); +BaseType_t xQueueCRReceiveFromISR( QueueHandle_t xQueue, void *pvBuffer, BaseType_t *pxTaskWoken ); +BaseType_t xQueueCRSend( QueueHandle_t xQueue, const void *pvItemToQueue, TickType_t xTicksToWait ); +BaseType_t xQueueCRReceive( QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait ); + +/* + * For internal use only. Use xSemaphoreCreateMutex(), + * xSemaphoreCreateCounting() or xSemaphoreGetMutexHolder() instead of calling + * these functions directly. + */ +QueueHandle_t xQueueCreateMutex( const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateMutexStatic( const uint8_t ucQueueType, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphore( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount ) PRIVILEGED_FUNCTION; +QueueHandle_t xQueueCreateCountingSemaphoreStatic( const UBaseType_t uxMaxCount, const UBaseType_t uxInitialCount, StaticQueue_t *pxStaticQueue ) PRIVILEGED_FUNCTION; +BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolder( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; +TaskHandle_t xQueueGetMutexHolderFromISR( QueueHandle_t xSemaphore ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Use xSemaphoreTakeMutexRecursive() or + * xSemaphoreGiveMutexRecursive() instead of calling these functions directly. + */ +BaseType_t xQueueTakeMutexRecursive( QueueHandle_t xMutex, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGiveMutexRecursive( QueueHandle_t xMutex ) PRIVILEGED_FUNCTION; + +/* + * Reset a queue back to its original empty state. The return value is now + * obsolete and is always set to pdPASS. + */ +#define xQueueReset( xQueue ) xQueueGenericReset( xQueue, pdFALSE ) + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger. If you are not using a kernel + * aware debugger then this function can be ignored. + * + * configQUEUE_REGISTRY_SIZE defines the maximum number of handles the + * registry can hold. configQUEUE_REGISTRY_SIZE must be greater than 0 + * within FreeRTOSConfig.h for the registry to be available. Its value + * does not effect the number of queues, semaphores and mutexes that can be + * created - just the number that the registry can hold. + * + * @param xQueue The handle of the queue being added to the registry. This + * is the handle returned by a call to xQueueCreate(). Semaphore and mutex + * handles can also be passed in here. + * + * @param pcName The name to be associated with the handle. This is the + * name that the kernel aware debugger will display. The queue registry only + * stores a pointer to the string - so the string must be persistent (global or + * preferably in ROM/Flash), not on the stack. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueAddToRegistry( QueueHandle_t xQueue, const char *pcQueueName ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * The registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call vQueueAddToRegistry() add + * a queue, semaphore or mutex handle to the registry if you want the handle + * to be available to a kernel aware debugger, and vQueueUnregisterQueue() to + * remove the queue, semaphore or mutex from the register. If you are not using + * a kernel aware debugger then this function can be ignored. + * + * @param xQueue The handle of the queue being removed from the registry. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +#endif + +/* + * The queue registry is provided as a means for kernel aware debuggers to + * locate queues, semaphores and mutexes. Call pcQueueGetName() to look + * up and return the name of a queue in the queue registry from the queue's + * handle. + * + * @param xQueue The handle of the queue the name of which will be returned. + * @return If the queue is in the registry then a pointer to the name of the + * queue is returned. If the queue is not in the registry then NULL is + * returned. + */ +#if( configQUEUE_REGISTRY_SIZE > 0 ) + const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreate( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Generic version of the function used to creaet a queue using dynamic memory + * allocation. This is called by other functions and macros that create other + * RTOS objects that use the queue structure as their base. + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType ) PRIVILEGED_FUNCTION; +#endif + +/* + * Queue sets provide a mechanism to allow a task to block (pend) on a read + * operation from multiple queues or semaphores simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * A queue set must be explicitly created using a call to xQueueCreateSet() + * before it can be used. Once created, standard FreeRTOS queues and semaphores + * can be added to the set using calls to xQueueAddToSet(). + * xQueueSelectFromSet() is then used to determine which, if any, of the queues + * or semaphores contained in the set is in a state where a queue read or + * semaphore take operation would be successful. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: An additional 4 bytes of RAM is required for each space in a every + * queue added to a queue set. Therefore counting semaphores that have a high + * maximum count value should not be added to a queue set. + * + * Note 4: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param uxEventQueueLength Queue sets store events that occur on + * the queues and semaphores contained in the set. uxEventQueueLength specifies + * the maximum number of events that can be queued at once. To be absolutely + * certain that events are not lost uxEventQueueLength should be set to the + * total sum of the length of the queues added to the set, where binary + * semaphores and mutexes have a length of 1, and counting semaphores have a + * length set by their maximum count value. Examples: + * + If a queue set is to hold a queue of length 5, another queue of length 12, + * and a binary semaphore, then uxEventQueueLength should be set to + * (5 + 12 + 1), or 18. + * + If a queue set is to hold three binary semaphores then uxEventQueueLength + * should be set to (1 + 1 + 1 ), or 3. + * + If a queue set is to hold a counting semaphore that has a maximum count of + * 5, and a counting semaphore that has a maximum count of 3, then + * uxEventQueueLength should be set to (5 + 3), or 8. + * + * @return If the queue set is created successfully then a handle to the created + * queue set is returned. Otherwise NULL is returned. + */ +QueueSetHandle_t xQueueCreateSet( const UBaseType_t uxEventQueueLength ) PRIVILEGED_FUNCTION; + +/* + * Adds a queue or semaphore to a queue set that was previously created by a + * call to xQueueCreateSet(). + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being added to + * the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set to which the queue or semaphore + * is being added. + * + * @return If the queue or semaphore was successfully added to the queue set + * then pdPASS is returned. If the queue could not be successfully added to the + * queue set because it is already a member of a different queue set then pdFAIL + * is returned. + */ +BaseType_t xQueueAddToSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * Removes a queue or semaphore from a queue set. A queue or semaphore can only + * be removed from a set if the queue or semaphore is empty. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * @param xQueueOrSemaphore The handle of the queue or semaphore being removed + * from the queue set (cast to an QueueSetMemberHandle_t type). + * + * @param xQueueSet The handle of the queue set in which the queue or semaphore + * is included. + * + * @return If the queue or semaphore was successfully removed from the queue set + * then pdPASS is returned. If the queue was not in the queue set, or the + * queue (or semaphore) was not empty, then pdFAIL is returned. + */ +BaseType_t xQueueRemoveFromSet( QueueSetMemberHandle_t xQueueOrSemaphore, QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* + * xQueueSelectFromSet() selects from the members of a queue set a queue or + * semaphore that either contains data (in the case of a queue) or is available + * to take (in the case of a semaphore). xQueueSelectFromSet() effectively + * allows a task to block (pend) on a read operation on all the queues and + * semaphores in a queue set simultaneously. + * + * See FreeRTOS/Source/Demo/Common/Minimal/QueueSet.c for an example using this + * function. + * + * Note 1: See the documentation on http://wwwFreeRTOS.org/RTOS-queue-sets.html + * for reasons why queue sets are very rarely needed in practice as there are + * simpler methods of blocking on multiple objects. + * + * Note 2: Blocking on a queue set that contains a mutex will not cause the + * mutex holder to inherit the priority of the blocked task. + * + * Note 3: A receive (in the case of a queue) or take (in the case of a + * semaphore) operation must not be performed on a member of a queue set unless + * a call to xQueueSelectFromSet() has first returned a handle to that set member. + * + * @param xQueueSet The queue set on which the task will (potentially) block. + * + * @param xTicksToWait The maximum time, in ticks, that the calling task will + * remain in the Blocked state (with other tasks executing) to wait for a member + * of the queue set to be ready for a successful queue read or semaphore take + * operation. + * + * @return xQueueSelectFromSet() will return the handle of a queue (cast to + * a QueueSetMemberHandle_t type) contained in the queue set that contains data, + * or the handle of a semaphore (cast to a QueueSetMemberHandle_t type) contained + * in the queue set that is available, or NULL if no such queue or semaphore + * exists before before the specified block time expires. + */ +QueueSetMemberHandle_t xQueueSelectFromSet( QueueSetHandle_t xQueueSet, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * A version of xQueueSelectFromSet() that can be used from an ISR. + */ +QueueSetMemberHandle_t xQueueSelectFromSetFromISR( QueueSetHandle_t xQueueSet ) PRIVILEGED_FUNCTION; + +/* Not public API functions. */ +void vQueueWaitForMessageRestricted( QueueHandle_t xQueue, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; +BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue ) PRIVILEGED_FUNCTION; +void vQueueSetQueueNumber( QueueHandle_t xQueue, UBaseType_t uxQueueNumber ) PRIVILEGED_FUNCTION; +UBaseType_t uxQueueGetQueueNumber( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; +uint8_t ucQueueGetQueueType( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; + +void vQueueEndScheduler(void); /* << EST */ + +#ifdef __cplusplus +} +#endif + +#endif /* QUEUE_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/readme_gdbBacktraceDebug.txt b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/readme_gdbBacktraceDebug.txt new file mode 100644 index 0000000..b4e0d4f --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/readme_gdbBacktraceDebug.txt @@ -0,0 +1,31 @@ +readme.txt +---------- +Tasks backtrace switcher/viewer snippet is from the following FreeRTOS Interactive site: +http://interactive.freertos.org/entries/23468301-Tasks-backtrace-switcher-viewer-snippet-for-debugger-gcc-gdb-ARM-Cortex-M3-MPU-port-Eclipse-support- + +It generates the following files: +- readme_gdbBacktraceDebug.txt (this file) +- .gdbinit-FreeRTOS-helpers (GDB script file) + +Usage: +- execute GDB script (either manually or in the launch configuration): + source .//Generated_Code//.gdbinit-FreeRTOS-helpers +- execute + freertos_show_threads + to show threads with handlers +- use + freertos_switch_to_task + to show task stack +- use + freertos_restore_running_context + to restore the context before running + +Credits to: +- Artem Pisarneko for his initial contribution +- Prasana for the PendSVHandler updates +- Geoffrey Wossum for the Cortex-M4 contribution + +Link to article: +http://mcuoneclipse.com/2015/10/03/freertos-arm-thread-debugging-with-eclipse-and-gdb/ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/semphr.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/semphr.h new file mode 100644 index 0000000..c901d9e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/semphr.h @@ -0,0 +1,1141 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef SEMAPHORE_H +#define SEMAPHORE_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h" must appear in source files before "include semphr.h" +#endif + +#include "queue.h" + +typedef QueueHandle_t SemaphoreHandle_t; + +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) + + +/** + * semphr. h + *
vSemaphoreCreateBinary( SemaphoreHandle_t xSemaphore )
+ * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * This old vSemaphoreCreateBinary() macro is now deprecated in favour of the + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * Macro that implements a semaphore by using the existing queue mechanism. + * The queue length is 1 as this is a binary semaphore. The data size is 0 + * as we don't want to actually store any data - we just want to know if the + * queue is empty or full. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param xSemaphore Handle to the created semaphore. Should be of type SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to vSemaphoreCreateBinary ().
+    // This is a macro so pass the variable in directly.
+    vSemaphoreCreateBinary( xSemaphore );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup vSemaphoreCreateBinary vSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define vSemaphoreCreateBinary( xSemaphore ) \ + { \ + ( xSemaphore ) = xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ); \ + if( ( xSemaphore ) != NULL ) \ + { \ + ( void ) xSemaphoreGive( ( xSemaphore ) ); \ + } \ + } +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinary( void )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * The old vSemaphoreCreateBinary() macro is now deprecated in favour of this + * xSemaphoreCreateBinary() function. Note that binary semaphores created using + * the vSemaphoreCreateBinary() macro are created in a state such that the + * first call to 'take' the semaphore would pass, whereas binary semaphores + * created using xSemaphoreCreateBinary() are created in a state such that the + * the semaphore must first be 'given' before it can be 'taken'. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @return Handle to the created semaphore, or NULL if the memory required to + * hold the semaphore's data structures could not be allocated. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateBinary xSemaphoreCreateBinary + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinary() xQueueGenericCreate( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateBinaryStatic( StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new binary semaphore instance, and returns a handle by which the + * new semaphore can be referenced. + * + * NOTE: In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a binary semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, binary semaphores use a block + * of memory, in which the semaphore structure is stored. If a binary semaphore + * is created using xSemaphoreCreateBinary() then the required memory is + * automatically dynamically allocated inside the xSemaphoreCreateBinary() + * function. (see http://www.freertos.org/a00111.html). If a binary semaphore + * is created using xSemaphoreCreateBinaryStatic() then the application writer + * must provide the memory. xSemaphoreCreateBinaryStatic() therefore allows a + * binary semaphore to be created without using any dynamic memory allocation. + * + * This type of semaphore can be used for pure synchronisation between tasks or + * between an interrupt and a task. The semaphore need not be given back once + * obtained, so one task/interrupt can continuously 'give' the semaphore while + * another continuously 'takes' the semaphore. For this reason this type of + * semaphore does not use a priority inheritance mechanism. For an alternative + * that does use priority inheritance see xSemaphoreCreateMutex(). + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the semaphore is created then a handle to the created semaphore is + * returned. If pxSemaphoreBuffer is NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateBinary().
+    // The semaphore's data structures will be placed in the xSemaphoreBuffer
+    // variable, the address of which is passed into the function.  The
+    // function's parameter is not NULL, so the function will not attempt any
+    // dynamic memory allocation, and therefore the function will not return
+    // return NULL.
+    xSemaphore = xSemaphoreCreateBinary( &xSemaphoreBuffer );
+
+    // Rest of task code goes here.
+ }
+ 
+ * \defgroup xSemaphoreCreateBinaryStatic xSemaphoreCreateBinaryStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateBinaryStatic( pxStaticSemaphore ) xQueueGenericCreateStatic( ( UBaseType_t ) 1, semSEMAPHORE_QUEUE_ITEM_LENGTH, NULL, pxStaticSemaphore, queueQUEUE_TYPE_BINARY_SEMAPHORE ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
xSemaphoreTake(
+ *                   SemaphoreHandle_t xSemaphore,
+ *                   TickType_t xBlockTime
+ *               )
+ * + * Macro to obtain a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). + * + * @param xSemaphore A handle to the semaphore being taken - obtained when + * the semaphore was created. + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. A block + * time of portMAX_DELAY can be used to block indefinitely (provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h). + * + * @return pdTRUE if the semaphore was obtained. pdFALSE + * if xBlockTime expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // A task that creates a semaphore.
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = xSemaphoreCreateBinary();
+ }
+
+ // A task that uses the semaphore.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xSemaphore != NULL )
+    {
+        // See if we can obtain the semaphore.  If the semaphore is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the semaphore and can now access the
+            // shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource.  Release the
+            // semaphore.
+            xSemaphoreGive( xSemaphore );
+        }
+        else
+        {
+            // We could not obtain the semaphore and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTake xSemaphoreTake + * \ingroup Semaphores + */ +#define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) + +/** + * semphr. h + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ) + * + * Macro to recursively obtain, or 'take', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being obtained. This is the + * handle returned by xSemaphoreCreateRecursiveMutex(); + * + * @param xBlockTime The time in ticks to wait for the semaphore to become + * available. The macro portTICK_PERIOD_MS can be used to convert this to a + * real time. A block time of zero can be used to poll the semaphore. If + * the task already owns the semaphore then xSemaphoreTakeRecursive() will + * return immediately no matter what the value of xBlockTime. + * + * @return pdTRUE if the semaphore was obtained. pdFALSE if xBlockTime + * expired without the semaphore becoming available. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xSemaphore, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+            // xSemaphoreTakeRecursive() are made on the same mutex.  In real
+            // code these would not be just sequential calls as this would make
+            // no sense.  Instead the calls are likely to be buried inside
+            // a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+            // available to another task until it has also been given back
+            // three times.  Again it is unlikely that real code would have
+            // these calls sequentially, but instead buried in a more complex
+            // call structure.  This is just for illustrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+            xSemaphoreGiveRecursive( xMutex );
+
+            // Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreTakeRecursive xSemaphoreTakeRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#endif + +/** + * semphr. h + *
xSemaphoreGive( SemaphoreHandle_t xSemaphore )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or + * xSemaphoreCreateCounting(). and obtained using sSemaphoreTake(). + * + * This macro must not be used from an ISR. See xSemaphoreGiveFromISR () for + * an alternative which can be used from an ISR. + * + * This macro must also not be used on semaphores created using + * xSemaphoreCreateRecursiveMutex(). + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @return pdTRUE if the semaphore was released. pdFALSE if an error occurred. + * Semaphores are implemented using queues. An error can occur if there is + * no space on the queue to post a message - indicating that the + * semaphore was not first obtained correctly. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ void vATask( void * pvParameters )
+ {
+    // Create the semaphore to guard a shared resource.
+    xSemaphore = vSemaphoreCreateBinary();
+
+    if( xSemaphore != NULL )
+    {
+        if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+        {
+            // We would expect this call to fail because we cannot give
+            // a semaphore without first "taking" it!
+        }
+
+        // Obtain the semaphore - don't block if the semaphore is not
+        // immediately available.
+        if( xSemaphoreTake( xSemaphore, ( TickType_t ) 0 ) )
+        {
+            // We now have the semaphore and can access the shared resource.
+
+            // ...
+
+            // We have finished accessing the shared resource so can free the
+            // semaphore.
+            if( xSemaphoreGive( xSemaphore ) != pdTRUE )
+            {
+                // We would not expect this call to fail because we must have
+                // obtained the semaphore to get here.
+            }
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGive xSemaphoreGive + * \ingroup Semaphores + */ +#define xSemaphoreGive( xSemaphore ) xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) + +/** + * semphr. h + *
xSemaphoreGiveRecursive( SemaphoreHandle_t xMutex )
+ * + * Macro to recursively release, or 'give', a mutex type semaphore. + * The mutex must have previously been created using a call to + * xSemaphoreCreateRecursiveMutex(); + * + * configUSE_RECURSIVE_MUTEXES must be set to 1 in FreeRTOSConfig.h for this + * macro to be available. + * + * This macro must not be used on mutexes created using xSemaphoreCreateMutex(). + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * @param xMutex A handle to the mutex being released, or 'given'. This is the + * handle returned by xSemaphoreCreateMutex(); + * + * @return pdTRUE if the semaphore was given. + * + * Example usage: +
+ SemaphoreHandle_t xMutex = NULL;
+
+ // A task that creates a mutex.
+ void vATask( void * pvParameters )
+ {
+    // Create the mutex to guard a shared resource.
+    xMutex = xSemaphoreCreateRecursiveMutex();
+ }
+
+ // A task that uses the mutex.
+ void vAnotherTask( void * pvParameters )
+ {
+    // ... Do other things.
+
+    if( xMutex != NULL )
+    {
+        // See if we can obtain the mutex.  If the mutex is not available
+        // wait 10 ticks to see if it becomes free.
+        if( xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 ) == pdTRUE )
+        {
+            // We were able to obtain the mutex and can now access the
+            // shared resource.
+
+            // ...
+            // For some reason due to the nature of the code further calls to
+			// xSemaphoreTakeRecursive() are made on the same mutex.  In real
+			// code these would not be just sequential calls as this would make
+			// no sense.  Instead the calls are likely to be buried inside
+			// a more complex call structure.
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+            xSemaphoreTakeRecursive( xMutex, ( TickType_t ) 10 );
+
+            // The mutex has now been 'taken' three times, so will not be
+			// available to another task until it has also been given back
+			// three times.  Again it is unlikely that real code would have
+			// these calls sequentially, it would be more likely that the calls
+			// to xSemaphoreGiveRecursive() would be called as a call stack
+			// unwound.  This is just for demonstrative purposes.
+            xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+			xSemaphoreGiveRecursive( xMutex );
+
+			// Now the mutex can be taken by other tasks.
+        }
+        else
+        {
+            // We could not obtain the mutex and can therefore not access
+            // the shared resource safely.
+        }
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveRecursive xSemaphoreGiveRecursive + * \ingroup Semaphores + */ +#if( configUSE_RECURSIVE_MUTEXES == 1 ) + #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#endif + +/** + * semphr. h + *
+ xSemaphoreGiveFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to release a semaphore. The semaphore must have previously been + * created with a call to xSemaphoreCreateBinary() or xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR. + * + * @param xSemaphore A handle to the semaphore being released. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreGiveFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if giving the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreGiveFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully given, otherwise errQUEUE_FULL. + * + * Example usage: +
+ \#define LONG_TIME 0xffff
+ \#define TICKS_TO_WAIT	10
+ SemaphoreHandle_t xSemaphore = NULL;
+
+ // Repetitive task.
+ void vATask( void * pvParameters )
+ {
+    for( ;; )
+    {
+        // We want this task to run every 10 ticks of a timer.  The semaphore
+        // was created before this task was started.
+
+        // Block waiting for the semaphore to become available.
+        if( xSemaphoreTake( xSemaphore, LONG_TIME ) == pdTRUE )
+        {
+            // It is time to execute.
+
+            // ...
+
+            // We have finished our task.  Return to the top of the loop where
+            // we will block on the semaphore until it is time to execute
+            // again.  Note when using the semaphore for synchronisation with an
+			// ISR in this manner there is no need to 'give' the semaphore back.
+        }
+    }
+ }
+
+ // Timer ISR
+ void vTimerISR( void * pvParameters )
+ {
+ static uint8_t ucLocalTickCount = 0;
+ static BaseType_t xHigherPriorityTaskWoken;
+
+    // A timer tick has occurred.
+
+    // ... Do other time functions.
+
+    // Is it time for vATask () to run?
+	xHigherPriorityTaskWoken = pdFALSE;
+    ucLocalTickCount++;
+    if( ucLocalTickCount >= TICKS_TO_WAIT )
+    {
+        // Unblock the task by releasing the semaphore.
+        xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
+
+        // Reset the count so we release the semaphore again in 10 ticks time.
+        ucLocalTickCount = 0;
+    }
+
+    if( xHigherPriorityTaskWoken != pdFALSE )
+    {
+        // We can force a context switch here.  Context switching from an
+        // ISR uses port specific syntax.  Check the demo task for your port
+        // to find the syntax required.
+    }
+ }
+ 
+ * \defgroup xSemaphoreGiveFromISR xSemaphoreGiveFromISR + * \ingroup Semaphores + */ +#define xSemaphoreGiveFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueGiveFromISR( ( QueueHandle_t ) ( xSemaphore ), ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
+ xSemaphoreTakeFromISR(
+                          SemaphoreHandle_t xSemaphore,
+                          BaseType_t *pxHigherPriorityTaskWoken
+                      )
+ * + * Macro to take a semaphore from an ISR. The semaphore must have + * previously been created with a call to xSemaphoreCreateBinary() or + * xSemaphoreCreateCounting(). + * + * Mutex type semaphores (those created using a call to xSemaphoreCreateMutex()) + * must not be used with this macro. + * + * This macro can be used from an ISR, however taking a semaphore from an ISR + * is not a common operation. It is likely to only be useful when taking a + * counting semaphore when an interrupt is obtaining an object from a resource + * pool (when the semaphore count indicates the number of resources available). + * + * @param xSemaphore A handle to the semaphore being taken. This is the + * handle returned when the semaphore was created. + * + * @param pxHigherPriorityTaskWoken xSemaphoreTakeFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if taking the semaphore caused a task + * to unblock, and the unblocked task has a priority higher than the currently + * running task. If xSemaphoreTakeFromISR() sets this value to pdTRUE then + * a context switch should be requested before the interrupt is exited. + * + * @return pdTRUE if the semaphore was successfully taken, otherwise + * pdFALSE + */ +#define xSemaphoreTakeFromISR( xSemaphore, pxHigherPriorityTaskWoken ) xQueueReceiveFromISR( ( QueueHandle_t ) ( xSemaphore ), NULL, ( pxHigherPriorityTaskWoken ) ) + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutex( void )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return If the mutex was successfully created then a handle to the created + * semaphore is returned. If there was not enough heap to allocate the mutex + * data structures then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateMutex xSemaphoreCreateMutex + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutex() xQueueCreateMutex( queueQUEUE_TYPE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new mutex type semaphore instance, and returns a handle by which + * the new mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, mutex semaphores use a block + * of memory, in which the mutex structure is stored. If a mutex is created + * using xSemaphoreCreateMutex() then the required memory is automatically + * dynamically allocated inside the xSemaphoreCreateMutex() function. (see + * http://www.freertos.org/a00111.html). If a mutex is created using + * xSemaphoreCreateMutexStatic() then the application writer must provided the + * memory. xSemaphoreCreateMutexStatic() therefore allows a mutex to be created + * without using any dynamic memory allocation. + * + * Mutexes created using this function can be accessed using the xSemaphoreTake() + * and xSemaphoreGive() macros. The xSemaphoreTakeRecursive() and + * xSemaphoreGiveRecursive() macros must not be used. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will be used to hold the mutex's data structure, removing the need for + * the memory to be allocated dynamically. + * + * @return If the mutex was successfully created then a handle to the created + * mutex is returned. If pxMutexBuffer was NULL then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A mutex cannot be used before it has been created.  xMutexBuffer is
+    // into xSemaphoreCreateMutexStatic() so no dynamic memory allocation is
+    // attempted.
+    xSemaphore = xSemaphoreCreateMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateMutexStatic xSemaphoreCreateMutexStatic + * \ingroup Semaphores + */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateMutexStatic( pxMutexBuffer ) xQueueCreateMutexStatic( queueQUEUE_TYPE_MUTEX, ( pxMutexBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @return xSemaphore Handle to the created mutex semaphore. Should be of type + * SemaphoreHandle_t. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+    // Semaphore cannot be used before a call to xSemaphoreCreateMutex().
+    // This is a macro so pass the variable in directly.
+    xSemaphore = xSemaphoreCreateRecursiveMutex();
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutex xSemaphoreCreateRecursiveMutex + * \ingroup Semaphores + */ +#if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutex() xQueueCreateMutex( queueQUEUE_TYPE_RECURSIVE_MUTEX ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateRecursiveMutexStatic( StaticSemaphore_t *pxMutexBuffer )
+ * + * Creates a new recursive mutex type semaphore instance, and returns a handle + * by which the new recursive mutex can be referenced. + * + * Internally, within the FreeRTOS implementation, recursive mutexs use a block + * of memory, in which the mutex structure is stored. If a recursive mutex is + * created using xSemaphoreCreateRecursiveMutex() then the required memory is + * automatically dynamically allocated inside the + * xSemaphoreCreateRecursiveMutex() function. (see + * http://www.freertos.org/a00111.html). If a recursive mutex is created using + * xSemaphoreCreateRecursiveMutexStatic() then the application writer must + * provide the memory that will get used by the mutex. + * xSemaphoreCreateRecursiveMutexStatic() therefore allows a recursive mutex to + * be created without using any dynamic memory allocation. + * + * Mutexes created using this macro can be accessed using the + * xSemaphoreTakeRecursive() and xSemaphoreGiveRecursive() macros. The + * xSemaphoreTake() and xSemaphoreGive() macros must not be used. + * + * A mutex used recursively can be 'taken' repeatedly by the owner. The mutex + * doesn't become available again until the owner has called + * xSemaphoreGiveRecursive() for each successful 'take' request. For example, + * if a task successfully 'takes' the same mutex 5 times then the mutex will + * not be available to any other task until it has also 'given' the mutex back + * exactly five times. + * + * This type of semaphore uses a priority inheritance mechanism so a task + * 'taking' a semaphore MUST ALWAYS 'give' the semaphore back once the + * semaphore it is no longer required. + * + * Mutex type semaphores cannot be used from within interrupt service routines. + * + * See xSemaphoreCreateBinary() for an alternative implementation that can be + * used for pure synchronisation (where one task or interrupt always 'gives' the + * semaphore and another always 'takes' the semaphore) and from within interrupt + * service routines. + * + * @param pxMutexBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the recursive mutex's data structure, + * removing the need for the memory to be allocated dynamically. + * + * @return If the recursive mutex was successfully created then a handle to the + * created recursive mutex is returned. If pxMutexBuffer was NULL then NULL is + * returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xMutexBuffer;
+
+ void vATask( void * pvParameters )
+ {
+    // A recursive semaphore cannot be used before it is created.  Here a
+    // recursive mutex is created using xSemaphoreCreateRecursiveMutexStatic().
+    // The address of xMutexBuffer is passed into the function, and will hold
+    // the mutexes data structures - so no dynamic memory allocation will be
+    // attempted.
+    xSemaphore = xSemaphoreCreateRecursiveMutexStatic( &xMutexBuffer );
+
+    // As no dynamic memory allocation was performed, xSemaphore cannot be NULL,
+    // so there is no need to check it.
+ }
+ 
+ * \defgroup xSemaphoreCreateRecursiveMutexStatic xSemaphoreCreateRecursiveMutexStatic + * \ingroup Semaphores + */ +#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_RECURSIVE_MUTEXES == 1 ) ) + #define xSemaphoreCreateRecursiveMutexStatic( pxStaticSemaphore ) xQueueCreateMutexStatic( queueQUEUE_TYPE_RECURSIVE_MUTEX, pxStaticSemaphore ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCounting( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer can + * instead optionally provide the memory that will get used by the counting + * semaphore. xSemaphoreCreateCountingStatic() therefore allows a counting + * semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @return Handle to the created semaphore. Null if the semaphore could not be + * created. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Semaphore cannot be used before a call to xSemaphoreCreateCounting().
+    // The max value to which the semaphore can count should be 10, and the
+    // initial value assigned to the count should be 0.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0 );
+
+    if( xSemaphore != NULL )
+    {
+        // The semaphore was created successfully.
+        // The semaphore can now be used.
+    }
+ }
+ 
+ * \defgroup xSemaphoreCreateCounting xSemaphoreCreateCounting + * \ingroup Semaphores + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCounting( uxMaxCount, uxInitialCount ) xQueueCreateCountingSemaphore( ( uxMaxCount ), ( uxInitialCount ) ) +#endif + +/** + * semphr. h + *
SemaphoreHandle_t xSemaphoreCreateCountingStatic( UBaseType_t uxMaxCount, UBaseType_t uxInitialCount, StaticSemaphore_t *pxSemaphoreBuffer )
+ * + * Creates a new counting semaphore instance, and returns a handle by which the + * new counting semaphore can be referenced. + * + * In many usage scenarios it is faster and more memory efficient to use a + * direct to task notification in place of a counting semaphore! + * http://www.freertos.org/RTOS-task-notifications.html + * + * Internally, within the FreeRTOS implementation, counting semaphores use a + * block of memory, in which the counting semaphore structure is stored. If a + * counting semaphore is created using xSemaphoreCreateCounting() then the + * required memory is automatically dynamically allocated inside the + * xSemaphoreCreateCounting() function. (see + * http://www.freertos.org/a00111.html). If a counting semaphore is created + * using xSemaphoreCreateCountingStatic() then the application writer must + * provide the memory. xSemaphoreCreateCountingStatic() therefore allows a + * counting semaphore to be created without using any dynamic memory allocation. + * + * Counting semaphores are typically used for two things: + * + * 1) Counting events. + * + * In this usage scenario an event handler will 'give' a semaphore each time + * an event occurs (incrementing the semaphore count value), and a handler + * task will 'take' a semaphore each time it processes an event + * (decrementing the semaphore count value). The count value is therefore + * the difference between the number of events that have occurred and the + * number that have been processed. In this case it is desirable for the + * initial count value to be zero. + * + * 2) Resource management. + * + * In this usage scenario the count value indicates the number of resources + * available. To obtain control of a resource a task must first obtain a + * semaphore - decrementing the semaphore count value. When the count value + * reaches zero there are no free resources. When a task finishes with the + * resource it 'gives' the semaphore back - incrementing the semaphore count + * value. In this case it is desirable for the initial count value to be + * equal to the maximum count value, indicating that all resources are free. + * + * @param uxMaxCount The maximum count value that can be reached. When the + * semaphore reaches this value it can no longer be 'given'. + * + * @param uxInitialCount The count value assigned to the semaphore when it is + * created. + * + * @param pxSemaphoreBuffer Must point to a variable of type StaticSemaphore_t, + * which will then be used to hold the semaphore's data structure, removing the + * need for the memory to be allocated dynamically. + * + * @return If the counting semaphore was successfully created then a handle to + * the created counting semaphore is returned. If pxSemaphoreBuffer was NULL + * then NULL is returned. + * + * Example usage: +
+ SemaphoreHandle_t xSemaphore;
+ StaticSemaphore_t xSemaphoreBuffer;
+
+ void vATask( void * pvParameters )
+ {
+ SemaphoreHandle_t xSemaphore = NULL;
+
+    // Counting semaphore cannot be used before they have been created.  Create
+    // a counting semaphore using xSemaphoreCreateCountingStatic().  The max
+    // value to which the semaphore can count is 10, and the initial value
+    // assigned to the count will be 0.  The address of xSemaphoreBuffer is
+    // passed in and will be used to hold the semaphore structure, so no dynamic
+    // memory allocation will be used.
+    xSemaphore = xSemaphoreCreateCounting( 10, 0, &xSemaphoreBuffer );
+
+    // No memory allocation was attempted so xSemaphore cannot be NULL, so there
+    // is no need to check its value.
+ }
+ 
+ * \defgroup xSemaphoreCreateCountingStatic xSemaphoreCreateCountingStatic + * \ingroup Semaphores + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + #define xSemaphoreCreateCountingStatic( uxMaxCount, uxInitialCount, pxSemaphoreBuffer ) xQueueCreateCountingSemaphoreStatic( ( uxMaxCount ), ( uxInitialCount ), ( pxSemaphoreBuffer ) ) +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * semphr. h + *
void vSemaphoreDelete( SemaphoreHandle_t xSemaphore );
+ * + * Delete a semaphore. This function must be used with care. For example, + * do not delete a mutex type semaphore if the mutex is held by a task. + * + * @param xSemaphore A handle to the semaphore to be deleted. + * + * \defgroup vSemaphoreDelete vSemaphoreDelete + * \ingroup Semaphores + */ +#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + * Note: This is a good way of determining if the calling task is the mutex + * holder, but not a good way of determining the identity of the mutex holder as + * the holder may change between the function exiting and the returned value + * being tested. + */ +#define xSemaphoreGetMutexHolder( xSemaphore ) xQueueGetMutexHolder( ( xSemaphore ) ) + +/** + * semphr.h + *
TaskHandle_t xSemaphoreGetMutexHolderFromISR( SemaphoreHandle_t xMutex );
+ * + * If xMutex is indeed a mutex type semaphore, return the current mutex holder. + * If xMutex is not a mutex type semaphore, or the mutex is available (not held + * by a task), return NULL. + * + */ +#define xSemaphoreGetMutexHolderFromISR( xSemaphore ) xQueueGetMutexHolderFromISR( ( xSemaphore ) ) + +/** + * semphr.h + *
UBaseType_t uxSemaphoreGetCount( SemaphoreHandle_t xSemaphore );
+ * + * If the semaphore is a counting semaphore then uxSemaphoreGetCount() returns + * its current count value. If the semaphore is a binary semaphore then + * uxSemaphoreGetCount() returns 1 if the semaphore is available, and 0 if the + * semaphore is not available. + * + */ +#define uxSemaphoreGetCount( xSemaphore ) uxQueueMessagesWaiting( ( QueueHandle_t ) ( xSemaphore ) ) + +#endif /* SEMAPHORE_H */ + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stack_macros.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stack_macros.h new file mode 100644 index 0000000..d6e4730 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stack_macros.h @@ -0,0 +1,130 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +#ifndef STACK_MACROS_H +#define STACK_MACROS_H + +/* + * Call the stack overflow hook function if the stack of the task being swapped + * out is currently overflowed, or looks like it might have overflowed in the + * past. + * + * Setting configCHECK_FOR_STACK_OVERFLOW to 1 will cause the macro to check + * the current stack state only - comparing the current top of stack value to + * the stack limit. Setting configCHECK_FOR_STACK_OVERFLOW to greater than 1 + * will also cause the last few stack bytes to be checked to ensure the value + * to which the bytes were set when the task was created have not been + * overwritten. Note this second test does not guarantee that an overflowed + * stack will always be recognised. + */ + +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH < 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack <= pxCurrentTCB->pxStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW == 1 ) && ( portSTACK_GROWTH > 0 ) ) + + /* Only the current stack state is to be checked. */ + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + \ + /* Is the currently saved stack pointer within the stack limit? */ \ + if( pxCurrentTCB->pxTopOfStack >= pxCurrentTCB->pxEndOfStack ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* configCHECK_FOR_STACK_OVERFLOW == 1 */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH < 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + const uint32_t * const pulStack = ( uint32_t * ) pxCurrentTCB->pxStack; \ + const uint32_t ulCheckValue = ( uint32_t ) 0xa5a5a5a5; \ + \ + if( ( pulStack[ 0 ] != ulCheckValue ) || \ + ( pulStack[ 1 ] != ulCheckValue ) || \ + ( pulStack[ 2 ] != ulCheckValue ) || \ + ( pulStack[ 3 ] != ulCheckValue ) ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName );/* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) && ( portSTACK_GROWTH > 0 ) ) + + #define taskCHECK_FOR_STACK_OVERFLOW() \ + { \ + int8_t *pcEndOfStack = ( int8_t * ) pxCurrentTCB->pxEndOfStack; \ + static const uint8_t ucExpectedStackBytes[] = { tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, \ + tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE, tskSTACK_FILL_BYTE }; \ + \ + \ + pcEndOfStack -= sizeof( ucExpectedStackBytes ); \ + \ + /* Has the extremity of the task stack ever been written over? */ \ + if( memcmp( ( void * ) pcEndOfStack, ( void * ) ucExpectedStackBytes, sizeof( ucExpectedStackBytes ) ) != 0 ) \ + { \ + configCHECK_FOR_STACK_OVERFLOW_NAME( ( TaskHandle_t ) pxCurrentTCB, pxCurrentTCB->pcTaskName ); /* << EST: use macro name */ \ + } \ + } + +#endif /* #if( configCHECK_FOR_STACK_OVERFLOW > 1 ) */ +/*-----------------------------------------------------------*/ + +/* Remove stack overflow macro if not being used. */ +#ifndef taskCHECK_FOR_STACK_OVERFLOW + #define taskCHECK_FOR_STACK_OVERFLOW() +#endif + + + +#endif /* STACK_MACROS_H */ + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.c new file mode 100644 index 0000000..d913af3 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.c @@ -0,0 +1,1271 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#if 1 /* << EST: handle HIWARE compiler and C++ mode, where UINT32_MAX does not exist */ +#ifndef __HIWARE__ /* C89 compiler does not know stdint.h */ + #include +#endif +#ifndef UINT32_MAX + #define UINT32_MAX 0xffffffff +#endif +#endif /* << EST */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "stream_buffer.h" + +#if( configUSE_TASK_NOTIFICATIONS != 1 ) + #error configUSE_TASK_NOTIFICATIONS must be set to 1 to build stream_buffer.c +#endif + +/* Lint e961, e9021 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* If the user has not provided application specific Rx notification macros, +or #defined the notification macros away, them provide default implementations +that uses task notifications. */ +/*lint -save -e9026 Function like macros allowed and needed here so they can be overidden. */ +#ifndef sbRECEIVE_COMPLETED + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbRECEIVE_COMPLETED */ + +#ifndef sbRECEIVE_COMPLETED_FROM_ISR + #define sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, \ + pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbRECEIVE_COMPLETED_FROM_ISR */ + +/* If the user has not provided an application specific Tx notification macro, +or #defined the notification macro away, them provide a default implementation +that uses task notifications. */ +#ifndef sbSEND_COMPLETED + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif /* sbSEND_COMPLETED */ + +#ifndef sbSEND_COMPLETE_FROM_ISR + #define sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ) \ + { \ + UBaseType_t uxSavedInterruptStatus; \ + \ + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction, \ + pxHigherPriorityTaskWoken ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \ + } +#endif /* sbSEND_COMPLETE_FROM_ISR */ +/*lint -restore (9026) */ + +/* The number of bytes used to hold the length of a message in the buffer. */ +#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) ) + +/* Bits stored in the ucFlags field of the stream buffer. */ +#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */ +#define sbFLAGS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 2 ) /* Set if the stream buffer was created using statically allocated memory. */ + +/*-----------------------------------------------------------*/ + +/* Structure that hold state information on the buffer. */ +typedef struct StreamBufferDef_t /*lint !e9058 Style convention uses tag. */ +{ + volatile size_t xTail; /* Index to the next item to read within the buffer. */ + volatile size_t xHead; /* Index to the next item to write within the buffer. */ + size_t xLength; /* The length of the buffer pointed to by pucBuffer. */ + size_t xTriggerLevelBytes; /* The number of bytes that must be in the stream buffer before a task that is waiting for data is unblocked. */ + volatile TaskHandle_t xTaskWaitingToReceive; /* Holds the handle of a task waiting for data, or NULL if no tasks are waiting. */ + volatile TaskHandle_t xTaskWaitingToSend; /* Holds the handle of a task waiting to send data to a message buffer that is full. */ + uint8_t *pucBuffer; /* Points to the buffer itself - that is - the RAM that stores the data passed through the buffer. */ + uint8_t ucFlags; + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ + #endif +} StreamBuffer_t; + +/* + * The number of bytes available to be read from the buffer. + */ +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) PRIVILEGED_FUNCTION; + +/* + * Add xCount bytes from pucData into the pxStreamBuffer message buffer. + * Returns the number of bytes written, which will either equal xCount in the + * success case, or 0 if there was not enough space in the buffer (in which case + * no data is written into the buffer). + */ +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then reads an entire + * message out of the buffer. If the stream buffer is being used as a stream + * buffer then read as many bytes as possible from the buffer. + * prvReadBytesFromBuffer() is called to actually extract the bytes from the + * buffer's data storage area. + */ +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) PRIVILEGED_FUNCTION; + +/* + * If the stream buffer is being used as a message buffer, then writes an entire + * message to the buffer. If the stream buffer is being used as a stream + * buffer then write as many bytes as possible to the buffer. + * prvWriteBytestoBuffer() is called to actually send the bytes to the buffer's + * data storage area. + */ +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) PRIVILEGED_FUNCTION; + +/* + * Read xMaxCount bytes from the pxStreamBuffer message buffer and write them + * to pucData. + */ +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, + uint8_t *pucData, + size_t xMaxCount, + size_t xBytesAvailable ) PRIVILEGED_FUNCTION; + +/* + * Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to + * initialise the members of the newly created stream buffer structure. + */ +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes, BaseType_t xIsMessageBuffer ) + { + uint8_t *pucAllocatedMemory; + uint8_t ucFlags; + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + if( xIsMessageBuffer == pdTRUE ) + { + /* Is a message buffer but not statically allocated. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER; + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* Not a message buffer and not statically allocated. */ + ucFlags = 0; + configASSERT( xBufferSizeBytes > 0 ); + } + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + /* A stream buffer requires a StreamBuffer_t structure and a buffer. + Both are allocated in a single call to pvPortMalloc(). The + StreamBuffer_t structure is placed at the start of the allocated memory + and the buffer follows immediately after. The requested size is + incremented so the free space is returned as the user would expect - + this is a quirk of the implementation that means otherwise the free + space would be reported as one byte smaller than would be logically + expected. */ + xBufferSizeBytes++; + pucAllocatedMemory = ( uint8_t * ) pvPortMalloc( xBufferSizeBytes + sizeof( StreamBuffer_t ) ); /*lint !e9079 malloc() only returns void*. */ + + if( pucAllocatedMemory != NULL ) + { + prvInitialiseNewStreamBuffer( ( StreamBuffer_t * ) pucAllocatedMemory, /* Structure at the start of the allocated memory. */ /*lint !e9087 Safe cast as allocated memory is aligned. */ /*lint !e826 Area is not too small and alignment is guaranteed provided malloc() behaves as expected and returns aligned buffer. */ + pucAllocatedMemory + sizeof( StreamBuffer_t ), /* Storage area follows. */ /*lint !e9016 Indexing past structure valid for uint8_t pointer, also storage area has no alignment requirement. */ + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + traceSTREAM_BUFFER_CREATE( ( ( StreamBuffer_t * ) pucAllocatedMemory ), xIsMessageBuffer ); + } + else + { + traceSTREAM_BUFFER_CREATE_FAILED( xIsMessageBuffer ); + } + + return ( StreamBufferHandle_t ) pucAllocatedMemory; /*lint !e9087 !e826 Safe cast as allocated memory is aligned. */ + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) + { + StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) pxStaticStreamBuffer; /*lint !e740 !e9087 Safe cast as StaticStreamBuffer_t is opaque Streambuffer_t. */ + StreamBufferHandle_t xReturn; + uint8_t ucFlags; + + configASSERT( pucStreamBufferStorageArea ); + configASSERT( pxStaticStreamBuffer ); + configASSERT( xTriggerLevelBytes <= xBufferSizeBytes ); + + /* A trigger level of 0 would cause a waiting task to unblock even when + the buffer was empty. */ + if( xTriggerLevelBytes == ( size_t ) 0 ) + { + xTriggerLevelBytes = ( size_t ) 1; + } + + if( xIsMessageBuffer != pdFALSE ) + { + /* Statically allocated message buffer. */ + ucFlags = sbFLAGS_IS_MESSAGE_BUFFER | sbFLAGS_IS_STATICALLY_ALLOCATED; + } + else + { + /* Statically allocated stream buffer. */ + ucFlags = sbFLAGS_IS_STATICALLY_ALLOCATED; + } + + /* In case the stream buffer is going to be used as a message buffer + (that is, it will hold discrete messages with a little meta data that + says how big the next message is) check the buffer will be large enough + to hold at least one message. */ + configASSERT( xBufferSizeBytes > sbBYTES_TO_STORE_MESSAGE_LENGTH ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticStreamBuffer_t equals the size of the real + message buffer structure. */ + volatile size_t xSize = sizeof( StaticStreamBuffer_t ); + configASSERT( xSize == sizeof( StreamBuffer_t ) ); + } /*lint !e529 xSize is referenced is configASSERT() is defined. */ + #endif /* configASSERT_DEFINED */ + + if( ( pucStreamBufferStorageArea != NULL ) && ( pxStaticStreamBuffer != NULL ) ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pucStreamBufferStorageArea, + xBufferSizeBytes, + xTriggerLevelBytes, + ucFlags ); + + /* Remember this was statically allocated in case it is ever deleted + again. */ + pxStreamBuffer->ucFlags |= sbFLAGS_IS_STATICALLY_ALLOCATED; + + traceSTREAM_BUFFER_CREATE( pxStreamBuffer, xIsMessageBuffer ); + + xReturn = ( StreamBufferHandle_t ) pxStaticStreamBuffer; /*lint !e9087 Data hiding requires cast to opaque type. */ + } + else + { + xReturn = NULL; + traceSTREAM_BUFFER_CREATE_STATIC_FAILED( xReturn, xIsMessageBuffer ); + } + + return xReturn; + } + +#endif /* ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + traceSTREAM_BUFFER_DELETE( xStreamBuffer ); + + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) pdFALSE ) + { + #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* Both the structure and the buffer were allocated using a single call + to pvPortMalloc(), hence only one call to vPortFree() is required. */ + vPortFree( ( void * ) pxStreamBuffer ); /*lint !e9087 Standard free() semantics require void *, plus pxStreamBuffer was allocated by pvPortMalloc(). */ + } + #else + { + /* Should not be possible to get here, ucFlags must be corrupt. + Force an assert. */ + configASSERT( xStreamBuffer == ( StreamBufferHandle_t ) ~0 ); + } + #endif + } + else + { + /* The structure and buffer were not allocated dynamically and cannot be + freed - just scrub the structure so future use will assert. */ + ( void ) memset( pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn = pdFAIL; + +#if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxStreamBufferNumber; +#endif + + configASSERT( pxStreamBuffer ); + + #if( configUSE_TRACE_FACILITY == 1 ) + { + /* Store the stream buffer number so it can be restored after the + reset. */ + uxStreamBufferNumber = pxStreamBuffer->uxStreamBufferNumber; + } + #endif + + /* Can only reset a message buffer if there are no tasks blocked on it. */ + taskENTER_CRITICAL(); + { + if( pxStreamBuffer->xTaskWaitingToReceive == NULL ) + { + if( pxStreamBuffer->xTaskWaitingToSend == NULL ) + { + prvInitialiseNewStreamBuffer( pxStreamBuffer, + pxStreamBuffer->pucBuffer, + pxStreamBuffer->xLength, + pxStreamBuffer->xTriggerLevelBytes, + pxStreamBuffer->ucFlags ); + xReturn = pdPASS; + + #if( configUSE_TRACE_FACILITY == 1 ) + { + pxStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + #endif + + traceSTREAM_BUFFER_RESET( xStreamBuffer ); + } + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; + + configASSERT( pxStreamBuffer ); + + /* It is not valid for the trigger level to be 0. */ + if( xTriggerLevel == ( size_t ) 0 ) + { + xTriggerLevel = ( size_t ) 1; + } + + /* The trigger level is the number of bytes that must be in the stream + buffer before a task that is waiting for data is unblocked. */ + if( xTriggerLevel <= pxStreamBuffer->xLength ) + { + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevel; + xReturn = pdPASS; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xSpace; + + configASSERT( pxStreamBuffer ); + + xSpace = pxStreamBuffer->xLength + pxStreamBuffer->xTail; + xSpace -= pxStreamBuffer->xHead; + xSpace -= ( size_t ) 1; + + if( xSpace >= pxStreamBuffer->xLength ) + { + xSpace -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xSpace; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn; + + configASSERT( pxStreamBuffer ); + + xReturn = prvBytesInBuffer( pxStreamBuffer ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace = 0; +size_t xRequiredSpace = xDataLengthBytes; +TimeOut_t xTimeOut; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + + /* Overflow? */ + configASSERT( xRequiredSpace > xDataLengthBytes ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + vTaskSetTimeOutState( &xTimeOut ); + + do + { + /* Wait until the required number of bytes are free in the message + buffer. */ + taskENTER_CRITICAL(); + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + + if( xSpace < xRequiredSpace ) + { + /* Clear notification state as going to wait for space. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one writer. */ + configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); + pxStreamBuffer->xTaskWaitingToSend = xTaskGetCurrentTaskHandle(); + } + else + { + taskEXIT_CRITICAL(); + break; + } + } + taskEXIT_CRITICAL(); + + traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToSend = NULL; + + } while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xSpace == ( size_t ) 0 ) + { + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + traceSTREAM_BUFFER_SEND( xStreamBuffer, xReturn ); + + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + traceSTREAM_BUFFER_SEND_FAILED( xStreamBuffer ); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xSpace; +size_t xRequiredSpace = xDataLengthBytes; + + configASSERT( pvTxData ); + configASSERT( pxStreamBuffer ); + + /* This send function is used to write to both message buffers and stream + buffers. If this is a message buffer then the space needed must be + increased by the amount of bytes needed to store the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xSpace = xStreamBufferSpacesAvailable( pxStreamBuffer ); + xReturn = prvWriteMessageToBuffer( pxStreamBuffer, pvTxData, xDataLengthBytes, xSpace, xRequiredSpace ); + + if( xReturn > ( size_t ) 0 ) + { + /* Was a task waiting for the data? */ + if( prvBytesInBuffer( pxStreamBuffer ) >= pxStreamBuffer->xTriggerLevelBytes ) + { + sbSEND_COMPLETE_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_SEND_FROM_ISR( xStreamBuffer, xReturn ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer, + const void * pvTxData, + size_t xDataLengthBytes, + size_t xSpace, + size_t xRequiredSpace ) +{ + BaseType_t xShouldWrite; + size_t xReturn; + + if( xSpace == ( size_t ) 0 ) + { + /* Doesn't matter if this is a stream buffer or a message buffer, there + is no space to write. */ + xShouldWrite = pdFALSE; + } + else if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) == ( uint8_t ) 0 ) + { + /* This is a stream buffer, as opposed to a message buffer, so writing a + stream of bytes rather than discrete messages. Write as many bytes as + possible. */ + xShouldWrite = pdTRUE; + xDataLengthBytes = configMIN( xDataLengthBytes, xSpace ); + } + else if( xSpace >= xRequiredSpace ) + { + /* This is a message buffer, as opposed to a stream buffer, and there + is enough space to write both the message length and the message itself + into the buffer. Start by writing the length of the data, the data + itself will be written later in this function. */ + xShouldWrite = pdTRUE; + ( void ) prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) &( xDataLengthBytes ), sbBYTES_TO_STORE_MESSAGE_LENGTH ); + } + else + { + /* There is space available, but not enough space. */ + xShouldWrite = pdFALSE; + } + + if( xShouldWrite != pdFALSE ) + { + /* Writes the data itself. */ + xReturn = prvWriteBytesToBuffer( pxStreamBuffer, ( const uint8_t * ) pvTxData, xDataLengthBytes ); /*lint !e9079 Storage buffer is implemented as uint8_t for ease of sizing, alighment and access. */ + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + if( xTicksToWait != ( TickType_t ) 0 ) + { + /* Checking if there is data and clearing the notification state must be + performed atomically. */ + taskENTER_CRITICAL(); + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* If this function was invoked by a message buffer read then + xBytesToStoreMessageLength holds the number of bytes used to hold + the length of the next discrete message. If this function was + invoked by a stream buffer read then xBytesToStoreMessageLength will + be 0. */ + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Clear notification state as going to wait for data. */ + ( void ) xTaskNotifyStateClear( NULL ); + + /* Should only be one reader. */ + configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); + pxStreamBuffer->xTaskWaitingToReceive = xTaskGetCurrentTaskHandle(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + if( xBytesAvailable <= xBytesToStoreMessageLength ) + { + /* Wait for data to be available. */ + traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer ); + ( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait ); + pxStreamBuffer->xTaskWaitingToReceive = NULL; + + /* Recheck the data available after blocking. */ + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + } + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + traceSTREAM_BUFFER_RECEIVE( xStreamBuffer, xReceivedLength ); + sbRECEIVE_COMPLETED( pxStreamBuffer ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + traceSTREAM_BUFFER_RECEIVE_FAILED( xStreamBuffer ); + mtCOVERAGE_TEST_MARKER(); + } + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReturn, xBytesAvailable, xOriginalTail; +configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn; + + configASSERT( pxStreamBuffer ); + + /* Ensure the stream buffer is being used as a message buffer. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH ) + { + /* The number of bytes available is greater than the number of bytes + required to hold the length of the next message, so another message + is available. Return its length without removing the length bytes + from the buffer. A copy of the tail is stored so the buffer can be + returned to its prior state as the message is not actually being + removed from the buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable ); + xReturn = ( size_t ) xTempReturn; + pxStreamBuffer->xTail = xOriginalTail; + } + else + { + /* The minimum amount of bytes in a message buffer is + ( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is + less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid + value is 0. */ + configASSERT( xBytesAvailable == 0 ); + xReturn = 0; + } + } + else + { + xReturn = 0; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength; + + configASSERT( pvRxData ); + configASSERT( pxStreamBuffer ); + + /* This receive function is used by both message buffers, which store + discrete messages, and stream buffers, which store a continuous stream of + bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the + message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + xBytesAvailable = prvBytesInBuffer( pxStreamBuffer ); + + /* Whether receiving a discrete message (where xBytesToStoreMessageLength + holds the number of bytes used to store the message length) or a stream of + bytes (where xBytesToStoreMessageLength is zero), the number of bytes + available must be greater than xBytesToStoreMessageLength to be able to + read bytes from the buffer. */ + if( xBytesAvailable > xBytesToStoreMessageLength ) + { + xReceivedLength = prvReadMessageFromBuffer( pxStreamBuffer, pvRxData, xBufferLengthBytes, xBytesAvailable, xBytesToStoreMessageLength ); + + /* Was a task waiting for space in the buffer? */ + if( xReceivedLength != ( size_t ) 0 ) + { + sbRECEIVE_COMPLETED_FROM_ISR( pxStreamBuffer, pxHigherPriorityTaskWoken ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceSTREAM_BUFFER_RECEIVE_FROM_ISR( xStreamBuffer, xReceivedLength ); + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + size_t xBytesAvailable, + size_t xBytesToStoreMessageLength ) +{ +size_t xOriginalTail, xReceivedLength, xNextMessageLength; +configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength; + + if( xBytesToStoreMessageLength != ( size_t ) 0 ) + { + /* A discrete message is being received. First receive the length + of the message. A copy of the tail is stored so the buffer can be + returned to its prior state if the length of the message is too + large for the provided buffer. */ + xOriginalTail = pxStreamBuffer->xTail; + ( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable ); + xNextMessageLength = ( size_t ) xTempNextMessageLength; + + /* Reduce the number of bytes available by the number of bytes just + read out. */ + xBytesAvailable -= xBytesToStoreMessageLength; + + /* Check there is enough space in the buffer provided by the + user. */ + if( xNextMessageLength > xBufferLengthBytes ) + { + /* The user has provided insufficient space to read the message + so return the buffer to its previous state (so the length of + the message is in the buffer again). */ + pxStreamBuffer->xTail = xOriginalTail; + xNextMessageLength = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* A stream of bytes is being received (as opposed to a discrete + message), so read as many bytes as possible. */ + xNextMessageLength = xBufferLengthBytes; + } + + /* Read the actual data. */ + xReceivedLength = prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) pvRxData, xNextMessageLength, xBytesAvailable ); /*lint !e9079 Data storage area is implemented as uint8_t array for ease of sizing, indexing and alignment. */ + + return xReceivedLength; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) +{ +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +size_t xTail; + + configASSERT( pxStreamBuffer ); + + /* True if no bytes are available. */ + xTail = pxStreamBuffer->xTail; + if( pxStreamBuffer->xHead == xTail ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) +{ +BaseType_t xReturn; +size_t xBytesToStoreMessageLength; +const StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; + + configASSERT( pxStreamBuffer ); + + /* This generic version of the receive function is used by both message + buffers, which store discrete messages, and stream buffers, which store a + continuous stream of bytes. Discrete messages include an additional + sbBYTES_TO_STORE_MESSAGE_LENGTH bytes that hold the length of the message. */ + if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 ) + { + xBytesToStoreMessageLength = sbBYTES_TO_STORE_MESSAGE_LENGTH; + } + else + { + xBytesToStoreMessageLength = 0; + } + + /* True if the available space equals zero. */ + if( xStreamBufferSpacesAvailable( xStreamBuffer ) <= xBytesToStoreMessageLength ) + { + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToReceive, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) +{ +StreamBuffer_t * const pxStreamBuffer = xStreamBuffer; +BaseType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + configASSERT( pxStreamBuffer ); + + uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) + { + ( void ) xTaskNotifyFromISR( ( pxStreamBuffer )->xTaskWaitingToSend, + ( uint32_t ) 0, + eNoAction, + pxHigherPriorityTaskWoken ); + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; + xReturn = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +static size_t prvWriteBytesToBuffer( StreamBuffer_t * const pxStreamBuffer, const uint8_t *pucData, size_t xCount ) +{ +size_t xNextHead, xFirstLength; + + configASSERT( xCount > ( size_t ) 0 ); + + xNextHead = pxStreamBuffer->xHead; + + /* Calculate the number of bytes that can be added in the first write - + which may be less than the total number of bytes that need to be added if + the buffer will wrap back to the beginning. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextHead, xCount ); + + /* Write as many bytes as can be written in the first write. */ + configASSERT( ( xNextHead + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void* ) ( &( pxStreamBuffer->pucBuffer[ xNextHead ] ) ), ( const void * ) pucData, xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the number of bytes written was less than the number that could be + written in the first write... */ + if( xCount > xFirstLength ) + { + /* ...then write the remaining bytes to the start of the buffer. */ + configASSERT( ( xCount - xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pxStreamBuffer->pucBuffer, ( const void * ) &( pucData[ xFirstLength ] ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + xNextHead += xCount; + if( xNextHead >= pxStreamBuffer->xLength ) + { + xNextHead -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxStreamBuffer->xHead = xNextHead; + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer, uint8_t *pucData, size_t xMaxCount, size_t xBytesAvailable ) +{ +size_t xCount, xFirstLength, xNextTail; + + /* Use the minimum of the wanted bytes and the available bytes. */ + xCount = configMIN( xBytesAvailable, xMaxCount ); + + if( xCount > ( size_t ) 0 ) + { + xNextTail = pxStreamBuffer->xTail; + + /* Calculate the number of bytes that can be read - which may be + less than the number wanted if the data wraps around to the start of + the buffer. */ + xFirstLength = configMIN( pxStreamBuffer->xLength - xNextTail, xCount ); + + /* Obtain the number of bytes it is possible to obtain in the first + read. Asserts check bounds of read and write. */ + configASSERT( xFirstLength <= xMaxCount ); + configASSERT( ( xNextTail + xFirstLength ) <= pxStreamBuffer->xLength ); + ( void ) memcpy( ( void * ) pucData, ( const void * ) &( pxStreamBuffer->pucBuffer[ xNextTail ] ), xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + + /* If the total number of wanted bytes is greater than the number + that could be read in the first read... */ + if( xCount > xFirstLength ) + { + /*...then read the remaining bytes from the start of the buffer. */ + configASSERT( xCount <= xMaxCount ); + ( void ) memcpy( ( void * ) &( pucData[ xFirstLength ] ), ( void * ) ( pxStreamBuffer->pucBuffer ), xCount - xFirstLength ); /*lint !e9087 memcpy() requires void *. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Move the tail pointer to effectively remove the data read from + the buffer. */ + xNextTail += xCount; + + if( xNextTail >= pxStreamBuffer->xLength ) + { + xNextTail -= pxStreamBuffer->xLength; + } + + pxStreamBuffer->xTail = xNextTail; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static size_t prvBytesInBuffer( const StreamBuffer_t * const pxStreamBuffer ) +{ +/* Returns the distance between xTail and xHead. */ +size_t xCount; + + xCount = pxStreamBuffer->xLength + pxStreamBuffer->xHead; + xCount -= pxStreamBuffer->xTail; + if ( xCount >= pxStreamBuffer->xLength ) + { + xCount -= pxStreamBuffer->xLength; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xCount; +} +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, + uint8_t * const pucBuffer, + size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + uint8_t ucFlags ) +{ + /* Assert here is deliberately writing to the entire buffer to ensure it can + be written to without generating exceptions, and is setting the buffer to a + known value to assist in development/debugging. */ + #if( configASSERT_DEFINED == 1 ) + { + /* The value written just has to be identifiable when looking at the + memory. Don't use 0xA5 as that is the stack fill value and could + result in confusion as to what is actually being observed. */ + const BaseType_t xWriteValue = 0x55; + configASSERT( memset( pucBuffer, ( int ) xWriteValue, xBufferSizeBytes ) == pucBuffer ); + } /*lint !e529 !e438 xWriteValue is only used if configASSERT() is defined. */ + #endif + + ( void ) memset( ( void * ) pxStreamBuffer, 0x00, sizeof( StreamBuffer_t ) ); /*lint !e9087 memset() requires void *. */ + pxStreamBuffer->pucBuffer = pucBuffer; + pxStreamBuffer->xLength = xBufferSizeBytes; + pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; + pxStreamBuffer->ucFlags = ucFlags; +} + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) + { + return xStreamBuffer->uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) + { + xStreamBuffer->uxStreamBufferNumber = uxStreamBufferNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) + { + return ( xStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ); + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.h new file mode 100644 index 0000000..7ed8612 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/stream_buffer.h @@ -0,0 +1,856 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* + * Stream buffers are used to send a continuous stream of data from one task or + * interrupt to another. Their implementation is light weight, making them + * particularly suited for interrupt to task and core to core communication + * scenarios. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section section and set the + * receive block time to 0. + * + */ + +#ifndef STREAM_BUFFER_H +#define STREAM_BUFFER_H + +#if defined( __cplusplus ) +extern "C" { +#endif + +/** + * Type by which stream buffers are referenced. For example, a call to + * xStreamBufferCreate() returns an StreamBufferHandle_t variable that can + * then be used as a parameter to xStreamBufferSend(), xStreamBufferReceive(), + * etc. + */ +struct StreamBufferDef_t; +typedef struct StreamBufferDef_t * StreamBufferHandle_t; + + +/** + * message_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreate( size_t xBufferSizeBytes, size_t xTriggerLevelBytes );
+
+ * + * Creates a new stream buffer using dynamically allocated memory. See + * xStreamBufferCreateStatic() for a version that uses statically allocated + * memory (memory that is allocated at compile time). + * + * configSUPPORT_DYNAMIC_ALLOCATION must be set to 1 or left undefined in + * FreeRTOSConfig.h for xStreamBufferCreate() to be available. + * + * @param xBufferSizeBytes The total number of bytes the stream buffer will be + * able to hold at any one time. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @return If NULL is returned, then the stream buffer cannot be created + * because there is insufficient heap memory available for FreeRTOS to allocate + * the stream buffer data structures and storage area. A non-NULL value being + * returned indicates that the stream buffer has been created successfully - + * the returned value should be stored as the handle to the created stream + * buffer. + * + * Example use: +
+
+void vAFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xStreamBufferSizeBytes = 100, xTriggerLevel = 10;
+
+    // Create a stream buffer that can hold 100 bytes.  The memory used to hold
+    // both the stream buffer structure and the data in the stream buffer is
+    // allocated dynamically.
+    xStreamBuffer = xStreamBufferCreate( xStreamBufferSizeBytes, xTriggerLevel );
+
+    if( xStreamBuffer == NULL )
+    {
+        // There was not enough heap memory space available to create the
+        // stream buffer.
+    }
+    else
+    {
+        // The stream buffer was created successfully and can now be used.
+    }
+}
+
+ * \defgroup xStreamBufferCreate xStreamBufferCreate + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreate( xBufferSizeBytes, xTriggerLevelBytes ) xStreamBufferGenericCreate( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE ) + +/** + * stream_buffer.h + * +
+StreamBufferHandle_t xStreamBufferCreateStatic( size_t xBufferSizeBytes,
+                                                size_t xTriggerLevelBytes,
+                                                uint8_t *pucStreamBufferStorageArea,
+                                                StaticStreamBuffer_t *pxStaticStreamBuffer );
+
+ * Creates a new stream buffer using statically allocated memory. See + * xStreamBufferCreate() for a version that uses dynamically allocated memory. + * + * configSUPPORT_STATIC_ALLOCATION must be set to 1 in FreeRTOSConfig.h for + * xStreamBufferCreateStatic() to be available. + * + * @param xBufferSizeBytes The size, in bytes, of the buffer pointed to by the + * pucStreamBufferStorageArea parameter. + * + * @param xTriggerLevelBytes The number of bytes that must be in the stream + * buffer before a task that is blocked on the stream buffer to wait for data is + * moved out of the blocked state. For example, if a task is blocked on a read + * of an empty stream buffer that has a trigger level of 1 then the task will be + * unblocked when a single byte is written to the buffer or the task's block + * time expires. As another example, if a task is blocked on a read of an empty + * stream buffer that has a trigger level of 10 then the task will not be + * unblocked until the stream buffer contains at least 10 bytes or the task's + * block time expires. If a reading task's block time expires before the + * trigger level is reached then the task will still receive however many bytes + * are actually available. Setting a trigger level of 0 will result in a + * trigger level of 1 being used. It is not valid to specify a trigger level + * that is greater than the buffer size. + * + * @param pucStreamBufferStorageArea Must point to a uint8_t array that is at + * least xBufferSizeBytes + 1 big. This is the array to which streams are + * copied when they are written to the stream buffer. + * + * @param pxStaticStreamBuffer Must point to a variable of type + * StaticStreamBuffer_t, which will be used to hold the stream buffer's data + * structure. + * + * @return If the stream buffer is created successfully then a handle to the + * created stream buffer is returned. If either pucStreamBufferStorageArea or + * pxStaticstreamBuffer are NULL then NULL is returned. + * + * Example use: +
+
+// Used to dimension the array used to hold the streams.  The available space
+// will actually be one less than this, so 999.
+#define STORAGE_SIZE_BYTES 1000
+
+// Defines the memory that will actually hold the streams within the stream
+// buffer.
+static uint8_t ucStorageBuffer[ STORAGE_SIZE_BYTES ];
+
+// The variable used to hold the stream buffer structure.
+StaticStreamBuffer_t xStreamBufferStruct;
+
+void MyFunction( void )
+{
+StreamBufferHandle_t xStreamBuffer;
+const size_t xTriggerLevel = 1;
+
+    xStreamBuffer = xStreamBufferCreateStatic( sizeof( ucBufferStorage ),
+                                               xTriggerLevel,
+                                               ucBufferStorage,
+                                               &xStreamBufferStruct );
+
+    // As neither the pucStreamBufferStorageArea or pxStaticStreamBuffer
+    // parameters were NULL, xStreamBuffer will not be NULL, and can be used to
+    // reference the created stream buffer in other stream buffer API calls.
+
+    // Other code that uses the stream buffer can go here.
+}
+
+
+ * \defgroup xStreamBufferCreateStatic xStreamBufferCreateStatic + * \ingroup StreamBufferManagement + */ +#define xStreamBufferCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pucStreamBufferStorageArea, pxStaticStreamBuffer ) xStreamBufferGenericCreateStatic( xBufferSizeBytes, xTriggerLevelBytes, pdFALSE, pucStreamBufferStorageArea, pxStaticStreamBuffer ) + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer,
+                          const void *pvTxData,
+                          size_t xDataLengthBytes,
+                          TickType_t xTicksToWait );
+
+ * + * Sends bytes to a stream buffer. The bytes are copied into the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the buffer that holds the bytes to be copied + * into the stream buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for enough space to become available in the stream + * buffer, should the stream buffer contain too little space to hold the + * another xDataLengthBytes bytes. The block time is specified in tick periods, + * so the absolute time it represents is dependent on the tick frequency. The + * macro pdMS_TO_TICKS() can be used to convert a time specified in milliseconds + * into a time specified in ticks. Setting xTicksToWait to portMAX_DELAY will + * cause the task to wait indefinitely (without timing out), provided + * INCLUDE_vTaskSuspend is set to 1 in FreeRTOSConfig.h. If a task times out + * before it can write all xDataLengthBytes into the buffer it will still write + * as many bytes as possible. A task does not use any CPU time when it is in + * the blocked state. + * + * @return The number of bytes written to the stream buffer. If a task times + * out before it can write all xDataLengthBytes into the buffer it will still + * write as many bytes as possible. + * + * Example use: +
+void vAFunction( StreamBufferHandle_t xStreamBuffer )
+{
+size_t xBytesSent;
+uint8_t ucArrayToSend[] = { 0, 1, 2, 3 };
+char *pcStringToSend = "String to send";
+const TickType_t x100ms = pdMS_TO_TICKS( 100 );
+
+    // Send an array to the stream buffer, blocking for a maximum of 100ms to
+    // wait for enough space to be available in the stream buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) ucArrayToSend, sizeof( ucArrayToSend ), x100ms );
+
+    if( xBytesSent != sizeof( ucArrayToSend ) )
+    {
+        // The call to xStreamBufferSend() times out before there was enough
+        // space in the buffer for the data to be written, but it did
+        // successfully write xBytesSent bytes.
+    }
+
+    // Send the string to the stream buffer.  Return immediately if there is not
+    // enough space in the buffer.
+    xBytesSent = xStreamBufferSend( xStreamBuffer, ( void * ) pcStringToSend, strlen( pcStringToSend ), 0 );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // The entire string could not be added to the stream buffer because
+        // there was not enough free space in the buffer, but xBytesSent bytes
+        // were sent.  Could try again to send the remaining bytes.
+    }
+}
+
+ * \defgroup xStreamBufferSend xStreamBufferSend + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer,
+                                 const void *pvTxData,
+                                 size_t xDataLengthBytes,
+                                 BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * Interrupt safe version of the API function that sends a stream of bytes to + * the stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferSend() to write to a stream buffer from a task. Use + * xStreamBufferSendFromISR() to write to a stream buffer from an interrupt + * service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer to which a stream is + * being sent. + * + * @param pvTxData A pointer to the data that is to be copied into the stream + * buffer. + * + * @param xDataLengthBytes The maximum number of bytes to copy from pvTxData + * into the stream buffer. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for data. Calling + * xStreamBufferSendFromISR() can make data available, and so cause a task that + * was waiting for data to leave the Blocked state. If calling + * xStreamBufferSendFromISR() causes a task to leave the Blocked state, and the + * unblocked task has a priority higher than the currently executing task (the + * task that was interrupted), then, internally, xStreamBufferSendFromISR() + * will set *pxHigherPriorityTaskWoken to pdTRUE. If + * xStreamBufferSendFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. This will + * ensure that the interrupt returns directly to the highest priority Ready + * state task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it + * is passed into the function. See the example code below for an example. + * + * @return The number of bytes actually written to the stream buffer, which will + * be less than xDataLengthBytes if the stream buffer didn't have enough free + * space for all the bytes to be written. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBufferHandle_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+size_t xBytesSent;
+char *pcStringToSend = "String to send";
+BaseType_t xHigherPriorityTaskWoken = pdFALSE; // Initialised to pdFALSE.
+
+    // Attempt to send the string to the stream buffer.
+    xBytesSent = xStreamBufferSendFromISR( xStreamBuffer,
+                                           ( void * ) pcStringToSend,
+                                           strlen( pcStringToSend ),
+                                           &xHigherPriorityTaskWoken );
+
+    if( xBytesSent != strlen( pcStringToSend ) )
+    {
+        // There was not enough free space in the stream buffer for the entire
+        // string to be written, ut xBytesSent bytes were written.
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferSendFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferSendFromISR xStreamBufferSendFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, + const void *pvTxData, + size_t xDataLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer,
+                             void *pvRxData,
+                             size_t xBufferLengthBytes,
+                             TickType_t xTicksToWait );
+
+ * + * Receives bytes from a stream buffer. + * + * ***NOTE***: Uniquely among FreeRTOS objects, the stream buffer + * implementation (so also the message buffer implementation, as message buffers + * are built on top of stream buffers) assumes there is only one task or + * interrupt that will write to the buffer (the writer), and only one task or + * interrupt that will read from the buffer (the reader). It is safe for the + * writer and reader to be different tasks or interrupts, but, unlike other + * FreeRTOS objects, it is not safe to have multiple different writers or + * multiple different readers. If there are to be multiple different writers + * then the application writer must place each call to a writing API function + * (such as xStreamBufferSend()) inside a critical section and set the send + * block time to 0. Likewise, if there are to be multiple different readers + * then the application writer must place each call to a reading API function + * (such as xStreamBufferRead()) inside a critical section and set the receive + * block time to 0. + * + * Use xStreamBufferReceive() to read from a stream buffer from a task. Use + * xStreamBufferReceiveFromISR() to read from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which bytes are to + * be received. + * + * @param pvRxData A pointer to the buffer into which the received bytes will be + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param xTicksToWait The maximum amount of time the task should remain in the + * Blocked state to wait for data to become available if the stream buffer is + * empty. xStreamBufferReceive() will return immediately if xTicksToWait is + * zero. The block time is specified in tick periods, so the absolute time it + * represents is dependent on the tick frequency. The macro pdMS_TO_TICKS() can + * be used to convert a time specified in milliseconds into a time specified in + * ticks. Setting xTicksToWait to portMAX_DELAY will cause the task to wait + * indefinitely (without timing out), provided INCLUDE_vTaskSuspend is set to 1 + * in FreeRTOSConfig.h. A task does not use any CPU time when it is in the + * Blocked state. + * + * @return The number of bytes actually read from the stream buffer, which will + * be less than xBufferLengthBytes if the call to xStreamBufferReceive() timed + * out before xBufferLengthBytes were available. + * + * Example use: +
+void vAFunction( StreamBuffer_t xStreamBuffer )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 20 );
+
+    // Receive up to another sizeof( ucRxData ) bytes from the stream buffer.
+    // Wait in the Blocked state (so not using any CPU processing time) for a
+    // maximum of 100ms for the full sizeof( ucRxData ) number of bytes to be
+    // available.
+    xReceivedBytes = xStreamBufferReceive( xStreamBuffer,
+                                           ( void * ) ucRxData,
+                                           sizeof( ucRxData ),
+                                           xBlockTime );
+
+    if( xReceivedBytes > 0 )
+    {
+        // A ucRxData contains another xRecievedBytes bytes of data, which can
+        // be processed here....
+    }
+}
+
+ * \defgroup xStreamBufferReceive xStreamBufferReceive + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
+                                    void *pvRxData,
+                                    size_t xBufferLengthBytes,
+                                    BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * An interrupt safe version of the API function that receives bytes from a + * stream buffer. + * + * Use xStreamBufferReceive() to read bytes from a stream buffer from a task. + * Use xStreamBufferReceiveFromISR() to read bytes from a stream buffer from an + * interrupt service routine (ISR). + * + * @param xStreamBuffer The handle of the stream buffer from which a stream + * is being received. + * + * @param pvRxData A pointer to the buffer into which the received bytes are + * copied. + * + * @param xBufferLengthBytes The length of the buffer pointed to by the + * pvRxData parameter. This sets the maximum number of bytes to receive in one + * call. xStreamBufferReceive will return as many bytes as possible up to a + * maximum set by xBufferLengthBytes. + * + * @param pxHigherPriorityTaskWoken It is possible that a stream buffer will + * have a task blocked on it waiting for space to become available. Calling + * xStreamBufferReceiveFromISR() can make space available, and so cause a task + * that is waiting for space to leave the Blocked state. If calling + * xStreamBufferReceiveFromISR() causes a task to leave the Blocked state, and + * the unblocked task has a priority higher than the currently executing task + * (the task that was interrupted), then, internally, + * xStreamBufferReceiveFromISR() will set *pxHigherPriorityTaskWoken to pdTRUE. + * If xStreamBufferReceiveFromISR() sets this value to pdTRUE, then normally a + * context switch should be performed before the interrupt is exited. That will + * ensure the interrupt returns directly to the highest priority Ready state + * task. *pxHigherPriorityTaskWoken should be set to pdFALSE before it is + * passed into the function. See the code example below for an example. + * + * @return The number of bytes read from the stream buffer, if any. + * + * Example use: +
+// A stream buffer that has already been created.
+StreamBuffer_t xStreamBuffer;
+
+void vAnInterruptServiceRoutine( void )
+{
+uint8_t ucRxData[ 20 ];
+size_t xReceivedBytes;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;  // Initialised to pdFALSE.
+
+    // Receive the next stream from the stream buffer.
+    xReceivedBytes = xStreamBufferReceiveFromISR( xStreamBuffer,
+                                                  ( void * ) ucRxData,
+                                                  sizeof( ucRxData ),
+                                                  &xHigherPriorityTaskWoken );
+
+    if( xReceivedBytes > 0 )
+    {
+        // ucRxData contains xReceivedBytes read from the stream buffer.
+        // Process the stream here....
+    }
+
+    // If xHigherPriorityTaskWoken was set to pdTRUE inside
+    // xStreamBufferReceiveFromISR() then a task that has a priority above the
+    // priority of the currently executing task was unblocked and a context
+    // switch should be performed to ensure the ISR returns to the unblocked
+    // task.  In most FreeRTOS ports this is done by simply passing
+    // xHigherPriorityTaskWoken into taskYIELD_FROM_ISR(), which will test the
+    // variables value, and perform the context switch if necessary.  Check the
+    // documentation for the port in use for port specific instructions.
+    taskYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+ * \defgroup xStreamBufferReceiveFromISR xStreamBufferReceiveFromISR + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, + void *pvRxData, + size_t xBufferLengthBytes, + BaseType_t * const pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Deletes a stream buffer that was previously created using a call to + * xStreamBufferCreate() or xStreamBufferCreateStatic(). If the stream + * buffer was created using dynamic memory (that is, by xStreamBufferCreate()), + * then the allocated memory is freed. + * + * A stream buffer handle must not be used after the stream buffer has been + * deleted. + * + * @param xStreamBuffer The handle of the stream buffer to be deleted. + * + * \defgroup vStreamBufferDelete vStreamBufferDelete + * \ingroup StreamBufferManagement + */ +void vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is full. A stream buffer is full if it + * does not have any free space, and therefore cannot accept any more data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is full then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsFull xStreamBufferIsFull + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see if it is empty. A stream buffer is empty if + * it does not contain any data. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return If the stream buffer is empty then pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferIsEmpty xStreamBufferIsEmpty + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferIsEmpty( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Resets a stream buffer to its initial, empty, state. Any data that was in + * the stream buffer is discarded. A stream buffer can only be reset if there + * are no tasks blocked waiting to either send to or receive from the stream + * buffer. + * + * @param xStreamBuffer The handle of the stream buffer being reset. + * + * @return If the stream buffer is reset then pdPASS is returned. If there was + * a task blocked waiting to send to or read from the stream buffer then the + * stream buffer is not reset and pdFAIL is returned. + * + * \defgroup xStreamBufferReset xStreamBufferReset + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReset( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much free space it contains, which is + * equal to the amount of data that can be sent to the stream buffer before it + * is full. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be written to the stream buffer before + * the stream buffer would be full. + * + * \defgroup xStreamBufferSpacesAvailable xStreamBufferSpacesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferSpacesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer );
+
+ * + * Queries a stream buffer to see how much data it contains, which is equal to + * the number of bytes that can be read from the stream buffer before the stream + * buffer would be empty. + * + * @param xStreamBuffer The handle of the stream buffer being queried. + * + * @return The number of bytes that can be read from the stream buffer before + * the stream buffer would be empty. + * + * \defgroup xStreamBufferBytesAvailable xStreamBufferBytesAvailable + * \ingroup StreamBufferManagement + */ +size_t xStreamBufferBytesAvailable( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel );
+
+ * + * A stream buffer's trigger level is the number of bytes that must be in the + * stream buffer before a task that is blocked on the stream buffer to + * wait for data is moved out of the blocked state. For example, if a task is + * blocked on a read of an empty stream buffer that has a trigger level of 1 + * then the task will be unblocked when a single byte is written to the buffer + * or the task's block time expires. As another example, if a task is blocked + * on a read of an empty stream buffer that has a trigger level of 10 then the + * task will not be unblocked until the stream buffer contains at least 10 bytes + * or the task's block time expires. If a reading task's block time expires + * before the trigger level is reached then the task will still receive however + * many bytes are actually available. Setting a trigger level of 0 will result + * in a trigger level of 1 being used. It is not valid to specify a trigger + * level that is greater than the buffer size. + * + * A trigger level is set when the stream buffer is created, and can be modified + * using xStreamBufferSetTriggerLevel(). + * + * @param xStreamBuffer The handle of the stream buffer being updated. + * + * @param xTriggerLevel The new trigger level for the stream buffer. + * + * @return If xTriggerLevel was less than or equal to the stream buffer's length + * then the trigger level will be updated and pdTRUE is returned. Otherwise + * pdFALSE is returned. + * + * \defgroup xStreamBufferSetTriggerLevel xStreamBufferSetTriggerLevel + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSetTriggerLevel( StreamBufferHandle_t xStreamBuffer, size_t xTriggerLevel ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbSEND_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is sent to a message buffer or stream buffer. If there was a task that + * was blocked on the message or stream buffer waiting for data to arrive then + * the sbSEND_COMPLETED() macro sends a notification to the task to remove it + * from the Blocked state. xStreamBufferSendCompletedFromISR() does the same + * thing. It is provided to enable application writers to implement their own + * version of sbSEND_COMPLETED(), and MUST NOT BE USED AT ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer to which data was + * written. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferSendCompletedFromISR(). If calling + * xStreamBufferSendCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferSendCompletedFromISR xStreamBufferSendCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferSendCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/** + * stream_buffer.h + * +
+BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken );
+
+ * + * For advanced users only. + * + * The sbRECEIVE_COMPLETED() macro is called from within the FreeRTOS APIs when + * data is read out of a message buffer or stream buffer. If there was a task + * that was blocked on the message or stream buffer waiting for data to arrive + * then the sbRECEIVE_COMPLETED() macro sends a notification to the task to + * remove it from the Blocked state. xStreamBufferReceiveCompletedFromISR() + * does the same thing. It is provided to enable application writers to + * implement their own version of sbRECEIVE_COMPLETED(), and MUST NOT BE USED AT + * ANY OTHER TIME. + * + * See the example implemented in FreeRTOS/Demo/Minimal/MessageBufferAMP.c for + * additional information. + * + * @param xStreamBuffer The handle of the stream buffer from which data was + * read. + * + * @param pxHigherPriorityTaskWoken *pxHigherPriorityTaskWoken should be + * initialised to pdFALSE before it is passed into + * xStreamBufferReceiveCompletedFromISR(). If calling + * xStreamBufferReceiveCompletedFromISR() removes a task from the Blocked state, + * and the task has a priority above the priority of the currently running task, + * then *pxHigherPriorityTaskWoken will get set to pdTRUE indicating that a + * context switch should be performed before exiting the ISR. + * + * @return If a task was removed from the Blocked state then pdTRUE is returned. + * Otherwise pdFALSE is returned. + * + * \defgroup xStreamBufferReceiveCompletedFromISR xStreamBufferReceiveCompletedFromISR + * \ingroup StreamBufferManagement + */ +BaseType_t xStreamBufferReceiveCompletedFromISR( StreamBufferHandle_t xStreamBuffer, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + +/* Functions below here are not part of the public API. */ +StreamBufferHandle_t xStreamBufferGenericCreate( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer ) PRIVILEGED_FUNCTION; + +StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes, + size_t xTriggerLevelBytes, + BaseType_t xIsMessageBuffer, + uint8_t * const pucStreamBufferStorageArea, + StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION; + +size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; + uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION; +#endif + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( STREAM_BUFFER_H ) */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/task.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/task.h new file mode 100644 index 0000000..85a5b07 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/task.h @@ -0,0 +1,2452 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef INC_TASK_H +#define INC_TASK_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include task.h" +#endif + +#include "list.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +#define tskKERNEL_VERSION_NUMBER "V10.2.1" +#define tskKERNEL_VERSION_MAJOR 10 +#define tskKERNEL_VERSION_MINOR 2 +#define tskKERNEL_VERSION_BUILD 1 + +/* MPU region parameters passed in ulParameters + * of MemoryRegion_t struct. */ +#define tskMPU_REGION_READ_ONLY ( 1UL << 0UL ) +#define tskMPU_REGION_READ_WRITE ( 1UL << 1UL ) +#define tskMPU_REGION_EXECUTE_NEVER ( 1UL << 2UL ) +#define tskMPU_REGION_NORMAL_MEMORY ( 1UL << 3UL ) +#define tskMPU_REGION_DEVICE_MEMORY ( 1UL << 4UL ) + +/** + * task. h + * + * Type by which tasks are referenced. For example, a call to xTaskCreate + * returns (via a pointer parameter) an TaskHandle_t variable that can then + * be used as a parameter to vTaskDelete to delete the task. + * + * \defgroup TaskHandle_t TaskHandle_t + * \ingroup Tasks + */ +struct tskTaskControlBlock; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tskTaskControlBlock* TaskHandle_t; + +/* + * Defines the prototype to which the application task hook function must + * conform. + */ +typedef BaseType_t (*TaskHookFunction_t)( void * ); + +/* Task states returned by eTaskGetState. */ +typedef enum +{ + eRunning = 0, /* A task is querying the state of itself, so must be running. */ + eReady, /* The task being queried is in a read or pending ready list. */ + eBlocked, /* The task being queried is in the Blocked state. */ + eSuspended, /* The task being queried is in the Suspended state, or is in the Blocked state with an infinite time out. */ + eDeleted, /* The task being queried has been deleted, but its TCB has not yet been freed. */ + eInvalid /* Used as an 'invalid state' value. */ +} eTaskState; + +/* Actions that can be performed when vTaskNotify() is called. */ +typedef enum +{ + eNoAction = 0, /* Notify the task without updating its notify value. */ + eSetBits, /* Set bits in the task's notification value. */ + eIncrement, /* Increment the task's notification value. */ + eSetValueWithOverwrite, /* Set the task's notification value to a specific value even if the previous value has not yet been read by the task. */ + eSetValueWithoutOverwrite /* Set the task's notification value if the previous value has been read by the task. */ +} eNotifyAction; + +/* + * Used internally only. + */ +typedef struct xTIME_OUT +{ + BaseType_t xOverflowCount; + TickType_t xTimeOnEntering; +} TimeOut_t; + +/* + * Defines the memory ranges allocated to the task when an MPU is used. + */ +typedef struct xMEMORY_REGION +{ + void *pvBaseAddress; + uint32_t ulLengthInBytes; + uint32_t ulParameters; +} MemoryRegion_t; + +/* + * Parameters required to create an MPU protected task. + */ +typedef struct xTASK_PARAMETERS +{ + TaskFunction_t pvTaskCode; + const char * const pcName; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + configSTACK_DEPTH_TYPE usStackDepth; + void *pvParameters; + UBaseType_t uxPriority; + StackType_t *puxStackBuffer; + MemoryRegion_t xRegions[ portNUM_CONFIGURABLE_REGIONS ]; + #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + StaticTask_t * const pxTaskBuffer; + #endif +} TaskParameters_t; + +/* Used with the uxTaskGetSystemState() function to return the state of each task +in the system. */ +typedef struct xTASK_STATUS +{ + TaskHandle_t xHandle; /* The handle of the task to which the rest of the information in the structure relates. */ + const char *pcTaskName; /* A pointer to the task's name. This value will be invalid if the task was deleted since the structure was populated! */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + UBaseType_t xTaskNumber; /* A number unique to the task. */ + eTaskState eCurrentState; /* The state in which the task existed when the structure was populated. */ + UBaseType_t uxCurrentPriority; /* The priority at which the task was running (may be inherited) when the structure was populated. */ + UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */ + uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */ + StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */ + configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */ +} TaskStatus_t; + +/* Possible return values for eTaskConfirmSleepModeStatus(). */ +typedef enum +{ + eAbortSleep = 0, /* A task has been made ready or a context switch pended since portSUPPORESS_TICKS_AND_SLEEP() was called - abort entering a sleep mode. */ + eStandardSleep, /* Enter a sleep mode that will not last any longer than the expected idle time. */ + eNoTasksWaitingTimeout /* No tasks are waiting for a timeout so it is safe to enter a sleep mode that can only be exited by an external interrupt. */ +} eSleepModeStatus; + +/** + * Defines the priority used by the idle task. This must not be modified. + * + * \ingroup TaskUtils + */ +#define tskIDLE_PRIORITY ( ( UBaseType_t ) 0U ) + +/** + * task. h + * + * Macro for forcing a context switch. + * + * \defgroup taskYIELD taskYIELD + * \ingroup SchedulerControl + */ +#define taskYIELD() portYIELD() + +/** + * task. h + * + * Macro to mark the start of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskENTER_CRITICAL taskENTER_CRITICAL + * \ingroup SchedulerControl + */ +#define taskENTER_CRITICAL() portENTER_CRITICAL() +#define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR() + +/** + * task. h + * + * Macro to mark the end of a critical code region. Preemptive context + * switches cannot occur when in a critical region. + * + * NOTE: This may alter the stack (depending on the portable implementation) + * so must be used with care! + * + * \defgroup taskEXIT_CRITICAL taskEXIT_CRITICAL + * \ingroup SchedulerControl + */ +#define taskEXIT_CRITICAL() portEXIT_CRITICAL() +#define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) +/** + * task. h + * + * Macro to disable all maskable interrupts. + * + * \defgroup taskDISABLE_INTERRUPTS taskDISABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskDISABLE_INTERRUPTS() portDISABLE_INTERRUPTS() + +/** + * task. h + * + * Macro to enable microcontroller interrupts. + * + * \defgroup taskENABLE_INTERRUPTS taskENABLE_INTERRUPTS + * \ingroup SchedulerControl + */ +#define taskENABLE_INTERRUPTS() portENABLE_INTERRUPTS() + +/* Definitions returned by xTaskGetSchedulerState(). taskSCHEDULER_SUSPENDED is +0 to generate more optimal code when configASSERT() is defined as the constant +is used in assert() statements. */ +#define taskSCHEDULER_SUSPENDED ( ( BaseType_t ) 0 ) +#define taskSCHEDULER_NOT_STARTED ( ( BaseType_t ) 1 ) +#define taskSCHEDULER_RUNNING ( ( BaseType_t ) 2 ) + + +/*----------------------------------------------------------- + * TASK CREATION API + *----------------------------------------------------------*/ + +/** + * task. h + *
+ BaseType_t xTaskCreate(
+							  TaskFunction_t pvTaskCode,
+							  const char * const pcName,
+							  configSTACK_DEPTH_TYPE usStackDepth,
+							  void *pvParameters,
+							  UBaseType_t uxPriority,
+							  TaskHandle_t *pvCreatedTask
+						  );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * See xTaskCreateStatic() for a version that does not use any dynamic memory + * allocation. + * + * xTaskCreate() can only be used to create a task that has unrestricted + * access to the entire microcontroller memory map. Systems that include MPU + * support can alternatively create an MPU constrained task using + * xTaskCreateRestricted(). + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. Max length defined by configMAX_TASK_NAME_LEN - default + * is 16. + * + * @param usStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 16 bits wide and usStackDepth is defined as 100, 200 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task should run. Systems that + * include MPU support can optionally create tasks in a privileged (system) + * mode by setting bit portPRIVILEGE_BIT of the priority parameter. For + * example, to create a privileged task at priority 2 the uxPriority parameter + * should be set to ( 2 | portPRIVILEGE_BIT ). + * + * @param pvCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+ // Task to be created.
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+	 }
+ }
+
+ // Function that creates a task.
+ void vOtherFunction( void )
+ {
+ static uint8_t ucParameterToPass;
+ TaskHandle_t xHandle = NULL;
+
+	 // Create the task, storing the handle.  Note that the passed parameter ucParameterToPass
+	 // must exist for the lifetime of the task, so in this case is declared static.  If it was just an
+	 // an automatic stack variable it might no longer exist, or at least have been corrupted, by the time
+	 // the new task attempts to access it.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, &ucParameterToPass, tskIDLE_PRIORITY, &xHandle );
+     configASSERT( xHandle );
+
+	 // Use the handle to delete the task.
+     if( xHandle != NULL )
+     {
+	     vTaskDelete( xHandle );
+     }
+ }
+   
+ * \defgroup xTaskCreate xTaskCreate + * \ingroup Tasks + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ TaskHandle_t xTaskCreateStatic( TaskFunction_t pvTaskCode,
+								 const char * const pcName,
+								 uint32_t ulStackDepth,
+								 void *pvParameters,
+								 UBaseType_t uxPriority,
+								 StackType_t *pxStackBuffer,
+								 StaticTask_t *pxTaskBuffer );
+ * + * Create a new task and add it to the list of tasks that are ready to run. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreate() then both blocks of memory are automatically dynamically + * allocated inside the xTaskCreate() function. (see + * http://www.freertos.org/a00111.html). If a task is created using + * xTaskCreateStatic() then the application writer must provide the required + * memory. xTaskCreateStatic() therefore allows a task to be created without + * using any dynamic memory allocation. + * + * @param pvTaskCode Pointer to the task entry function. Tasks + * must be implemented to never return (i.e. continuous loop). + * + * @param pcName A descriptive name for the task. This is mainly used to + * facilitate debugging. The maximum length of the string is defined by + * configMAX_TASK_NAME_LEN in FreeRTOSConfig.h. + * + * @param ulStackDepth The size of the task stack specified as the number of + * variables the stack can hold - not the number of bytes. For example, if + * the stack is 32-bits wide and ulStackDepth is defined as 100 then 400 bytes + * will be allocated for stack storage. + * + * @param pvParameters Pointer that will be used as the parameter for the task + * being created. + * + * @param uxPriority The priority at which the task will run. + * + * @param pxStackBuffer Must point to a StackType_t array that has at least + * ulStackDepth indexes - the array will then be used as the task's stack, + * removing the need for the stack to be allocated dynamically. + * + * @param pxTaskBuffer Must point to a variable of type StaticTask_t, which will + * then be used to hold the task's data structures, removing the need for the + * memory to be allocated dynamically. + * + * @return If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will + * be created and a handle to the created task is returned. If either + * pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and + * NULL is returned. + * + * Example usage: +
+
+    // Dimensions the buffer that the task being created will use as its stack.
+    // NOTE:  This is the number of words the stack will hold, not the number of
+    // bytes.  For example, if each stack item is 32-bits, and this is set to 100,
+    // then 400 bytes (100 * 32-bits) will be allocated.
+    #define STACK_SIZE 200
+
+    // Structure that will hold the TCB of the task being created.
+    StaticTask_t xTaskBuffer;
+
+    // Buffer that the task being created will use as its stack.  Note this is
+    // an array of StackType_t variables.  The size of StackType_t is dependent on
+    // the RTOS port.
+    StackType_t xStack[ STACK_SIZE ];
+
+    // Function that implements the task being created.
+    void vTaskCode( void * pvParameters )
+    {
+        // The parameter value is expected to be 1 as 1 is passed in the
+        // pvParameters value in the call to xTaskCreateStatic().
+        configASSERT( ( uint32_t ) pvParameters == 1UL );
+
+        for( ;; )
+        {
+            // Task code goes here.
+        }
+    }
+
+    // Function that creates a task.
+    void vOtherFunction( void )
+    {
+        TaskHandle_t xHandle = NULL;
+
+        // Create the task without using any dynamic memory allocation.
+        xHandle = xTaskCreateStatic(
+                      vTaskCode,       // Function that implements the task.
+                      "NAME",          // Text name for the task.
+                      STACK_SIZE,      // Stack size in words, not bytes.
+                      ( void * ) 1,    // Parameter passed into the task.
+                      tskIDLE_PRIORITY,// Priority at which the task is created.
+                      xStack,          // Array to use as the task's stack.
+                      &xTaskBuffer );  // Variable to hold the task's data structure.
+
+        // puxStackBuffer and pxTaskBuffer were not NULL, so the task will have
+        // been created, and xHandle will be the task's handle.  Use the handle
+        // to suspend the task.
+        vTaskSuspend( xHandle );
+    }
+   
+ * \defgroup xTaskCreateStatic xTaskCreateStatic + * \ingroup Tasks + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * task. h + *
+ BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * + * xTaskCreateRestricted() should only be used in systems that include an MPU + * implementation. + * + * Create a new task and add it to the list of tasks that are ready to run. + * The function parameters define the memory regions and associated access + * permissions allocated to the task. + * + * See xTaskCreateRestrictedStatic() for a version that does not use any + * dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +#if( portUSING_MPU_WRAPPERS == 1 ) + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask );
+ * + * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. + * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * + * Internally, within the FreeRTOS implementation, tasks use two blocks of + * memory. The first block is used to hold the task's data structures. The + * second block is used by the task as its stack. If a task is created using + * xTaskCreateRestricted() then the stack is provided by the application writer, + * and the memory used to hold the task's data structure is automatically + * dynamically allocated inside the xTaskCreateRestricted() function. If a task + * is created using xTaskCreateRestrictedStatic() then the application writer + * must provide the memory used to hold the task's data structures too. + * xTaskCreateRestrictedStatic() therefore allows a memory protected task to be + * created without using any dynamic memory allocation. + * + * @param pxTaskDefinition Pointer to a structure that contains a member + * for each of the normal xTaskCreate() parameters (see the xTaskCreate() API + * documentation) plus an optional stack buffer and the memory region + * definitions. If configSUPPORT_STATIC_ALLOCATION is set to 1 the structure + * contains an additional member, which is used to point to a variable of type + * StaticTask_t - which is then used to hold the task's data structure. + * + * @param pxCreatedTask Used to pass back a handle by which the created task + * can be referenced. + * + * @return pdPASS if the task was successfully created and added to a ready + * list, otherwise an error code defined in the file projdefs.h + * + * Example usage: +
+// Create an TaskParameters_t structure that defines the task to be created.
+// The StaticTask_t variable is only included in the structure when
+// configSUPPORT_STATIC_ALLOCATION is set to 1.  The PRIVILEGED_DATA macro can
+// be used to force the variable into the RTOS kernel's privileged data area.
+static PRIVILEGED_DATA StaticTask_t xTaskBuffer;
+static const TaskParameters_t xCheckTaskParameters =
+{
+	vATask,		// pvTaskCode - the function that implements the task.
+	"ATask",	// pcName - just a text name for the task to assist debugging.
+	100,		// usStackDepth	- the stack size DEFINED IN WORDS.
+	NULL,		// pvParameters - passed into the task function as the function parameters.
+	( 1UL | portPRIVILEGE_BIT ),// uxPriority - task priority, set the portPRIVILEGE_BIT if the task should run in a privileged state.
+	cStackBuffer,// puxStackBuffer - the buffer to be used as the task stack.
+
+	// xRegions - Allocate up to three separate memory regions for access by
+	// the task, with appropriate access permissions.  Different processors have
+	// different memory alignment requirements - refer to the FreeRTOS documentation
+	// for full information.
+	{
+		// Base address					Length	Parameters
+        { cReadWriteArray,				32,		portMPU_REGION_READ_WRITE },
+        { cReadOnlyArray,				32,		portMPU_REGION_READ_ONLY },
+        { cPrivilegedOnlyAccessArray,	128,	portMPU_REGION_PRIVILEGED_READ_WRITE }
+	}
+
+	&xTaskBuffer; // Holds the task's data structure.
+};
+
+int main( void )
+{
+TaskHandle_t xHandle;
+
+	// Create a task from the const structure defined above.  The task handle
+	// is requested (the second parameter is not NULL) but in this case just for
+	// demonstration purposes as its not actually used.
+	xTaskCreateRestricted( &xRegTest1Parameters, &xHandle );
+
+	// Start the scheduler.
+	vTaskStartScheduler();
+
+	// Will only get here if there was insufficient memory to create the idle
+	// and/or timer task.
+	for( ;; );
+}
+   
+ * \defgroup xTaskCreateRestrictedStatic xTaskCreateRestrictedStatic + * \ingroup Tasks + */ +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION; +#endif + +/** + * task. h + *
+ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions );
+ * + * Memory regions are assigned to a restricted task when the task is created by + * a call to xTaskCreateRestricted(). These regions can be redefined using + * vTaskAllocateMPURegions(). + * + * @param xTask The handle of the task being updated. + * + * @param xRegions A pointer to an MemoryRegion_t structure that contains the + * new memory region definitions. + * + * Example usage: +
+// Define an array of MemoryRegion_t structures that configures an MPU region
+// allowing read/write access for 1024 bytes starting at the beginning of the
+// ucOneKByte array.  The other two of the maximum 3 definable regions are
+// unused so set to zero.
+static const MemoryRegion_t xAltRegions[ portNUM_CONFIGURABLE_REGIONS ] =
+{
+	// Base address		Length		Parameters
+	{ ucOneKByte,		1024,		portMPU_REGION_READ_WRITE },
+	{ 0,				0,			0 },
+	{ 0,				0,			0 }
+};
+
+void vATask( void *pvParameters )
+{
+	// This task was created such that it has access to certain regions of
+	// memory as defined by the MPU configuration.  At some point it is
+	// desired that these MPU regions are replaced with that defined in the
+	// xAltRegions const struct above.  Use a call to vTaskAllocateMPURegions()
+	// for this purpose.  NULL is used as the task handle to indicate that this
+	// function should modify the MPU regions of the calling task.
+	vTaskAllocateMPURegions( NULL, xAltRegions );
+
+	// Now the task can continue its function, but from this point on can only
+	// access its stack and the ucOneKByte array (unless any other statically
+	// defined or shared regions have been declared elsewhere).
+}
+   
+ * \defgroup xTaskCreateRestricted xTaskCreateRestricted + * \ingroup Tasks + */ +void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelete( TaskHandle_t xTask );
+ * + * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Remove a task from the RTOS real time kernel's management. The task being + * deleted will be removed from all ready, blocked, suspended and event lists. + * + * NOTE: The idle task is responsible for freeing the kernel allocated + * memory from tasks that have been deleted. It is therefore important that + * the idle task is not starved of microcontroller processing time if your + * application makes any calls to vTaskDelete (). Memory allocated by the + * task code is not automatically freed, and should be freed before the task + * is deleted. + * + * See the demo application file death.c for sample code that utilises + * vTaskDelete (). + * + * @param xTask The handle of the task to be deleted. Passing NULL will + * cause the calling task to be deleted. + * + * Example usage: +
+ void vOtherFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create the task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // Use the handle to delete the task.
+	 vTaskDelete( xHandle );
+ }
+   
+ * \defgroup vTaskDelete vTaskDelete + * \ingroup Tasks + */ +void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK CONTROL API + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskDelay( const TickType_t xTicksToDelay );
+ * + * Delay a task for a given number of ticks. The actual time that the + * task remains blocked depends on the tick rate. The constant + * portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * INCLUDE_vTaskDelay must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * + * vTaskDelay() specifies a time at which the task wishes to unblock relative to + * the time at which vTaskDelay() is called. For example, specifying a block + * period of 100 ticks will cause the task to unblock 100 ticks after + * vTaskDelay() is called. vTaskDelay() does not therefore provide a good method + * of controlling the frequency of a periodic task as the path taken through the + * code, as well as other task and interrupt activity, will effect the frequency + * at which vTaskDelay() gets called and therefore the time at which the task + * next executes. See vTaskDelayUntil() for an alternative API function designed + * to facilitate fixed frequency execution. It does this by specifying an + * absolute time (rather than a relative time) at which the calling task should + * unblock. + * + * @param xTicksToDelay The amount of time, in tick periods, that + * the calling task should block. + * + * Example usage: + + void vTaskFunction( void * pvParameters ) + { + // Block for 500ms. + const TickType_t xDelay = 500 / portTICK_PERIOD_MS; + + for( ;; ) + { + // Simply toggle the LED every 500ms, blocking between each toggle. + vToggleLED(); + vTaskDelay( xDelay ); + } + } + + * \defgroup vTaskDelay vTaskDelay + * \ingroup TaskCtrl + */ +void vTaskDelay( const TickType_t xTicksToDelay ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskDelayUntil( TickType_t *pxPreviousWakeTime, const TickType_t xTimeIncrement );
+ * + * INCLUDE_vTaskDelayUntil must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Delay a task until a specified time. This function can be used by periodic + * tasks to ensure a constant execution frequency. + * + * This function differs from vTaskDelay () in one important aspect: vTaskDelay () will + * cause a task to block for the specified number of ticks from the time vTaskDelay () is + * called. It is therefore difficult to use vTaskDelay () by itself to generate a fixed + * execution frequency as the time between a task starting to execute and that task + * calling vTaskDelay () may not be fixed [the task may take a different path though the + * code between calls, or may get interrupted or preempted a different number of times + * each time it executes]. + * + * Whereas vTaskDelay () specifies a wake time relative to the time at which the function + * is called, vTaskDelayUntil () specifies the absolute (exact) time at which it wishes to + * unblock. + * + * The constant portTICK_PERIOD_MS can be used to calculate real time from the tick + * rate - with the resolution of one tick period. + * + * @param pxPreviousWakeTime Pointer to a variable that holds the time at which the + * task was last unblocked. The variable must be initialised with the current time + * prior to its first use (see the example below). Following this the variable is + * automatically updated within vTaskDelayUntil (). + * + * @param xTimeIncrement The cycle time period. The task will be unblocked at + * time *pxPreviousWakeTime + xTimeIncrement. Calling vTaskDelayUntil with the + * same xTimeIncrement parameter value will cause the task to execute with + * a fixed interface period. + * + * Example usage: +
+ // Perform an action every 10 ticks.
+ void vTaskFunction( void * pvParameters )
+ {
+ TickType_t xLastWakeTime;
+ const TickType_t xFrequency = 10;
+
+	 // Initialise the xLastWakeTime variable with the current time.
+	 xLastWakeTime = xTaskGetTickCount ();
+	 for( ;; )
+	 {
+		 // Wait for the next cycle.
+		 vTaskDelayUntil( &xLastWakeTime, xFrequency );
+
+		 // Perform action here.
+	 }
+ }
+   
+ * \defgroup vTaskDelayUntil vTaskDelayUntil + * \ingroup TaskCtrl + */ +void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskAbortDelay( TaskHandle_t xTask );
+ * + * INCLUDE_xTaskAbortDelay must be defined as 1 in FreeRTOSConfig.h for this + * function to be available. + * + * A task will enter the Blocked state when it is waiting for an event. The + * event it is waiting for can be a temporal event (waiting for a time), such + * as when vTaskDelay() is called, or an event on an object, such as when + * xQueueReceive() or ulTaskNotifyTake() is called. If the handle of a task + * that is in the Blocked state is used in a call to xTaskAbortDelay() then the + * task will leave the Blocked state, and return from whichever function call + * placed the task into the Blocked state. + * + * @param xTask The handle of the task to remove from the Blocked state. + * + * @return If the task referenced by xTask was not in the Blocked state then + * pdFAIL is returned. Otherwise pdPASS is returned. + * + * \defgroup xTaskAbortDelay xTaskAbortDelay + * \ingroup TaskCtrl + */ +BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskPriorityGet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the priority of any task. + * + * @param xTask Handle of the task to be queried. Passing a NULL + * handle results in the priority of the calling task being returned. + * + * @return The priority of xTask. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to obtain the priority of the created task.
+	 // It was created with tskIDLE_PRIORITY, but may have changed
+	 // it itself.
+	 if( uxTaskPriorityGet( xHandle ) != tskIDLE_PRIORITY )
+	 {
+		 // The task has changed it's priority.
+	 }
+
+	 // ...
+
+	 // Is our priority higher than the created task?
+	 if( uxTaskPriorityGet( xHandle ) < uxTaskPriorityGet( NULL ) )
+	 {
+		 // Our priority (obtained using NULL handle) is higher.
+	 }
+ }
+   
+ * \defgroup uxTaskPriorityGet uxTaskPriorityGet + * \ingroup TaskCtrl + */ +UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask );
+ * + * A version of uxTaskPriorityGet() that can be used from an ISR. + */ +UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
eTaskState eTaskGetState( TaskHandle_t xTask );
+ * + * INCLUDE_eTaskGetState must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Obtain the state of any task. States are encoded by the eTaskState + * enumerated type. + * + * @param xTask Handle of the task to be queried. + * + * @return The state of xTask at the time the function was called. Note the + * state of the task might change between the function being called, and the + * functions return value being tested by the calling task. + */ +eTaskState eTaskGetState( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState );
+ * + * configUSE_TRACE_FACILITY must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * Populates a TaskStatus_t structure with information about a task. + * + * @param xTask Handle of the task being queried. If xTask is NULL then + * information will be returned about the calling task. + * + * @param pxTaskStatus A pointer to the TaskStatus_t structure that will be + * filled with information about the task referenced by the handle passed using + * the xTask parameter. + * + * @xGetFreeStackSpace The TaskStatus_t structure contains a member to report + * the stack high water mark of the task being queried. Calculating the stack + * high water mark takes a relatively long time, and can make the system + * temporarily unresponsive - so the xGetFreeStackSpace parameter is provided to + * allow the high water mark checking to be skipped. The high watermark value + * will only be written to the TaskStatus_t structure if xGetFreeStackSpace is + * not set to pdFALSE; + * + * @param eState The TaskStatus_t structure contains a member to report the + * state of the task being queried. Obtaining the task state is not as fast as + * a simple assignment - so the eState parameter is provided to allow the state + * information to be omitted from the TaskStatus_t structure. To obtain state + * information then set eState to eInvalid - otherwise the value passed in + * eState will be reported as the task state in the TaskStatus_t structure. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+ TaskStatus_t xTaskDetails;
+
+    // Obtain the handle of a task from its name.
+    xHandle = xTaskGetHandle( "Task_Name" );
+
+    // Check the handle is not NULL.
+    configASSERT( xHandle );
+
+    // Use the handle to obtain further information about the task.
+    vTaskGetInfo( xHandle,
+                  &xTaskDetails,
+                  pdTRUE, // Include the high water mark in xTaskDetails.
+                  eInvalid ); // Include the task state in xTaskDetails.
+ }
+   
+ * \defgroup vTaskGetInfo vTaskGetInfo + * \ingroup TaskCtrl + */ +void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority );
+ * + * INCLUDE_vTaskPrioritySet must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Set the priority of any task. + * + * A context switch will occur before the function returns if the priority + * being set is higher than the currently executing task. + * + * @param xTask Handle to the task for which the priority is being set. + * Passing a NULL handle results in the priority of the calling task being set. + * + * @param uxNewPriority The priority to which the task will be set. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to raise the priority of the created task.
+	 vTaskPrioritySet( xHandle, tskIDLE_PRIORITY + 1 );
+
+	 // ...
+
+	 // Use a NULL handle to raise our priority to the same value.
+	 vTaskPrioritySet( NULL, tskIDLE_PRIORITY + 1 );
+ }
+   
+ * \defgroup vTaskPrioritySet vTaskPrioritySet + * \ingroup TaskCtrl + */ +void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspend( TaskHandle_t xTaskToSuspend );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Suspend any task. When suspended a task will never get any microcontroller + * processing time, no matter what its priority. + * + * Calls to vTaskSuspend are not accumulative - + * i.e. calling vTaskSuspend () twice on the same task still only requires one + * call to vTaskResume () to ready the suspended task. + * + * @param xTaskToSuspend Handle to the task being suspended. Passing a NULL + * handle will cause the calling task to be suspended. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Suspend ourselves.
+	 vTaskSuspend( NULL );
+
+	 // We cannot get here unless another task calls vTaskResume
+	 // with our handle as the parameter.
+ }
+   
+ * \defgroup vTaskSuspend vTaskSuspend + * \ingroup TaskCtrl + */ +void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskResume( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. + * See the configuration section for more information. + * + * Resumes a suspended task. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * vTaskResume (). + * + * @param xTaskToResume Handle to the task being readied. + * + * Example usage: +
+ void vAFunction( void )
+ {
+ TaskHandle_t xHandle;
+
+	 // Create a task, storing the handle.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, &xHandle );
+
+	 // ...
+
+	 // Use the handle to suspend the created task.
+	 vTaskSuspend( xHandle );
+
+	 // ...
+
+	 // The created task will not run during this period, unless
+	 // another task calls vTaskResume( xHandle ).
+
+	 //...
+
+
+	 // Resume the suspended task ourselves.
+	 vTaskResume( xHandle );
+
+	 // The created task will once again get microcontroller processing
+	 // time in accordance with its priority within the system.
+ }
+   
+ * \defgroup vTaskResume vTaskResume + * \ingroup TaskCtrl + */ +void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void xTaskResumeFromISR( TaskHandle_t xTaskToResume );
+ * + * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be + * available. See the configuration section for more information. + * + * An implementation of vTaskResume() that can be called from within an ISR. + * + * A task that has been suspended by one or more calls to vTaskSuspend () + * will be made available for running again by a single call to + * xTaskResumeFromISR (). + * + * xTaskResumeFromISR() should not be used to synchronise a task with an + * interrupt if there is a chance that the interrupt could arrive prior to the + * task being suspended - as this can lead to interrupts being missed. Use of a + * semaphore as a synchronisation mechanism would avoid this eventuality. + * + * @param xTaskToResume Handle to the task being readied. + * + * @return pdTRUE if resuming the task should result in a context switch, + * otherwise pdFALSE. This is used by the ISR to determine if a context switch + * may be required following the ISR. + * + * \defgroup vTaskResumeFromISR vTaskResumeFromISR + * \ingroup TaskCtrl + */ +BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * SCHEDULER CONTROL + *----------------------------------------------------------*/ + +/** + * task. h + *
void vTaskStartScheduler( void );
+ * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * + * See the demo application file main.c for an example of creating + * tasks and starting the kernel. + * + * Example usage: +
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will not get here unless a task calls vTaskEndScheduler ()
+ }
+   
+ * + * \defgroup vTaskStartScheduler vTaskStartScheduler + * \ingroup SchedulerControl + */ +void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskEndScheduler( void );
+ * + * NOTE: At the time of writing only the x86 real mode port, which runs on a PC + * in place of DOS, implements this function. + * + * Stops the real time kernel tick. All created tasks will be automatically + * deleted and multitasking (either preemptive or cooperative) will + * stop. Execution then resumes from the point where vTaskStartScheduler () + * was called, as if vTaskStartScheduler () had just returned. + * + * See the demo application file main. c in the demo/PC directory for an + * example that uses vTaskEndScheduler (). + * + * vTaskEndScheduler () requires an exit function to be defined within the + * portable layer (see vPortEndScheduler () in port. c for the PC port). This + * performs hardware specific operations such as stopping the kernel tick. + * + * vTaskEndScheduler () will cause all of the resources allocated by the + * kernel to be freed - but will not free resources allocated by application + * tasks. + * + * Example usage: +
+ void vTaskCode( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // At some point we want to end the real time kernel processing
+		 // so call ...
+		 vTaskEndScheduler ();
+	 }
+ }
+
+ void vAFunction( void )
+ {
+	 // Create at least one task before starting the kernel.
+	 xTaskCreate( vTaskCode, "NAME", STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
+
+	 // Start the real time kernel with preemption.
+	 vTaskStartScheduler ();
+
+	 // Will only get here when the vTaskCode () task has called
+	 // vTaskEndScheduler ().  When we get here we are back to single task
+	 // execution.
+ }
+   
+ * + * \defgroup vTaskEndScheduler vTaskEndScheduler + * \ingroup SchedulerControl + */ +void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskSuspendAll( void );
+ * + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. + * + * After calling vTaskSuspendAll () the calling task will continue to execute + * without risk of being swapped out until a call to xTaskResumeAll () has been + * made. + * + * API functions that have the potential to cause a context switch (for example, + * vTaskDelayUntil(), xQueueSend(), etc.) must not be called while the scheduler + * is suspended. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the kernel
+		 // tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.
+		 xTaskResumeAll ();
+	 }
+ }
+   
+ * \defgroup vTaskSuspendAll vTaskSuspendAll + * \ingroup SchedulerControl + */ +void vTaskSuspendAll( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskResumeAll( void );
+ * + * Resumes scheduler activity after it was suspended by a call to + * vTaskSuspendAll(). + * + * xTaskResumeAll() only resumes the scheduler. It does not unsuspend tasks + * that were previously suspended by a call to vTaskSuspend(). + * + * @return If resuming the scheduler caused a context switch then pdTRUE is + * returned, otherwise pdFALSE is returned. + * + * Example usage: +
+ void vTask1( void * pvParameters )
+ {
+	 for( ;; )
+	 {
+		 // Task code goes here.
+
+		 // ...
+
+		 // At some point the task wants to perform a long operation during
+		 // which it does not want to get swapped out.  It cannot use
+		 // taskENTER_CRITICAL ()/taskEXIT_CRITICAL () as the length of the
+		 // operation may cause interrupts to be missed - including the
+		 // ticks.
+
+		 // Prevent the real time kernel swapping out the task.
+		 vTaskSuspendAll ();
+
+		 // Perform the operation here.  There is no need to use critical
+		 // sections as we have all the microcontroller processing time.
+		 // During this time interrupts will still operate and the real
+		 // time kernel tick count will be maintained.
+
+		 // ...
+
+		 // The operation is complete.  Restart the kernel.  We want to force
+		 // a context switch - but there is no point if resuming the scheduler
+		 // caused a context switch already.
+		 if( !xTaskResumeAll () )
+		 {
+			  taskYIELD ();
+		 }
+	 }
+ }
+   
+ * \defgroup xTaskResumeAll xTaskResumeAll + * \ingroup SchedulerControl + */ +BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; + +/*----------------------------------------------------------- + * TASK UTILITIES + *----------------------------------------------------------*/ + +/** + * task. h + *
TickType_t xTaskGetTickCount( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * \defgroup xTaskGetTickCount xTaskGetTickCount + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
TickType_t xTaskGetTickCountFromISR( void );
+ * + * @return The count of ticks since vTaskStartScheduler was called. + * + * This is a version of xTaskGetTickCount() that is safe to be called from an + * ISR - provided that TickType_t is the natural word size of the + * microcontroller being used or interrupt nesting is either not supported or + * not being used. + * + * \defgroup xTaskGetTickCountFromISR xTaskGetTickCountFromISR + * \ingroup TaskUtils + */ +TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
uint16_t uxTaskGetNumberOfTasks( void );
+ * + * @return The number of tasks that the real time kernel is currently managing. + * This includes all ready, blocked and suspended tasks. A task that + * has been deleted but not yet freed by the idle task will also be + * included in the count. + * + * \defgroup uxTaskGetNumberOfTasks uxTaskGetNumberOfTasks + * \ingroup TaskUtils + */ +UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
char *pcTaskGetName( TaskHandle_t xTaskToQuery );
+ * + * @return The text (human readable) name of the task referenced by the handle + * xTaskToQuery. A task can query its own name by either passing in its own + * handle, or by setting xTaskToQuery to NULL. + * + * \defgroup pcTaskGetName pcTaskGetName + * \ingroup TaskUtils + */ +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
TaskHandle_t xTaskGetHandle( const char *pcNameToQuery );
+ * + * NOTE: This function takes a relatively long time to complete and should be + * used sparingly. + * + * @return The handle of the task that has the human readable name pcNameToQuery. + * NULL is returned if no matching name is found. INCLUDE_xTaskGetHandle + * must be set to 1 in FreeRTOSConfig.h for pcTaskGetHandle() to be available. + * + * \defgroup pcTaskGetHandle pcTaskGetHandle + * \ingroup TaskUtils + */ +TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task.h + *
UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/** + * task.h + *
configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask );
+ * + * INCLUDE_uxTaskGetStackHighWaterMark2 must be set to 1 in FreeRTOSConfig.h for + * this function to be available. + * + * Returns the high water mark of the stack associated with xTask. That is, + * the minimum free stack space there has been (in words, so on a 32 bit machine + * a value of 1 means 4 bytes) since the task started. The smaller the returned + * number the closer the task has come to overflowing its stack. + * + * uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + * same except for their return type. Using configSTACK_DEPTH_TYPE allows the + * user to determine the return type. It gets around the problem of the value + * overflowing on 8-bit types without breaking backward compatibility for + * applications that expect an 8-bit return type. + * + * @param xTask Handle of the task associated with the stack to be checked. + * Set xTask to NULL to check the stack of the calling task. + * + * @return The smallest amount of free stack space there has been (in words, so + * actual spaces on the stack rather than bytes) since the task referenced by + * xTask was created. + */ +configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* When using trace macros it is sometimes necessary to include task.h before +FreeRTOS.h. When this is done TaskHookFunction_t will not yet have been defined, +so the following two prototypes will cause a compilation error. This can be +fixed by simply guarding against the inclusion of these two prototypes unless +they are explicitly required by the configUSE_APPLICATION_TASK_TAG configuration +constant. */ +#ifdef configUSE_APPLICATION_TASK_TAG + #if configUSE_APPLICATION_TASK_TAG == 1 + /** + * task.h + *
void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction );
+ * + * Sets pxHookFunction to be the task hook function used by the task xTask. + * Passing xTask as NULL has the effect of setting the calling tasks hook + * function. + */ + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTag( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Do not + * call from an interrupt service routine - call + * xTaskGetApplicationTaskTagFromISR() instead. + */ + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + + /** + * task.h + *
void xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask );
+ * + * Returns the pxHookFunction value assigned to the task xTask. Can + * be called from an interrupt service routine. + */ + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + #endif /* configUSE_APPLICATION_TASK_TAG ==1 */ +#endif /* ifdef configUSE_APPLICATION_TASK_TAG */ + +#if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + + /* Each task contains an array of pointers that is dimensioned by the + configNUM_THREAD_LOCAL_STORAGE_POINTERS setting in FreeRTOSConfig.h. The + kernel does not use the pointers itself, so the application writer can use + the pointers for any purpose they wish. The following two functions are + used to set and query a pointer respectively. */ + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) PRIVILEGED_FUNCTION; + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) PRIVILEGED_FUNCTION; + +#endif + +/** + * task.h + *
BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter );
+ * + * Calls the hook function associated with xTask. Passing xTask as NULL has + * the effect of calling the Running tasks (the calling task) hook function. + * + * pvParameter is passed to the hook function for the task to interpret as it + * wants. The return value is the value returned by the task hook function + * registered by the user. + */ +BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) PRIVILEGED_FUNCTION; + +/** + * xTaskGetIdleTaskHandle() is only available if + * INCLUDE_xTaskGetIdleTaskHandle is set to 1 in FreeRTOSConfig.h. + * + * Simply returns the handle of the idle task. It is not valid to call + * xTaskGetIdleTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTaskGetIdleTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * configUSE_TRACE_FACILITY must be defined as 1 in FreeRTOSConfig.h for + * uxTaskGetSystemState() to be available. + * + * uxTaskGetSystemState() populates an TaskStatus_t structure for each task in + * the system. TaskStatus_t structures contain, among other things, members + * for the task handle, task name, task priority, task state, and total amount + * of run time consumed by the task. See the TaskStatus_t structure + * definition in this file for the full member list. + * + * NOTE: This function is intended for debugging use only as its use results in + * the scheduler remaining suspended for an extended period. + * + * @param pxTaskStatusArray A pointer to an array of TaskStatus_t structures. + * The array must contain at least one TaskStatus_t structure for each task + * that is under the control of the RTOS. The number of tasks under the control + * of the RTOS can be determined using the uxTaskGetNumberOfTasks() API function. + * + * @param uxArraySize The size of the array pointed to by the pxTaskStatusArray + * parameter. The size is specified as the number of indexes in the array, or + * the number of TaskStatus_t structures contained in the array, not by the + * number of bytes in the array. + * + * @param pulTotalRunTime If configGENERATE_RUN_TIME_STATS is set to 1 in + * FreeRTOSConfig.h then *pulTotalRunTime is set by uxTaskGetSystemState() to the + * total run time (as defined by the run time stats clock, see + * http://www.freertos.org/rtos-run-time-stats.html) since the target booted. + * pulTotalRunTime can be set to NULL to omit the total run time information. + * + * @return The number of TaskStatus_t structures that were populated by + * uxTaskGetSystemState(). This should equal the number returned by the + * uxTaskGetNumberOfTasks() API function, but will be zero if the value passed + * in the uxArraySize parameter was too small. + * + * Example usage: +
+    // This example demonstrates how a human readable table of run time stats
+	// information is generated from raw data provided by uxTaskGetSystemState().
+	// The human readable table is written to pcWriteBuffer
+	void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) // < 0 )
+			{
+				// For each populated position in the pxTaskStatusArray array,
+				// format the raw data as human readable ASCII data
+				for( x = 0; x < uxArraySize; x++ )
+				{
+					// What percentage of the total run time has the task used?
+					// This will always be rounded down to the nearest integer.
+					// ulTotalRunTimeDiv100 has already been divided by 100.
+					ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalRunTime;
+
+					if( ulStatsAsPercentage > 0UL )
+					{
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage );
+					}
+					else
+					{
+						// If the percentage is zero here then the task has
+						// consumed less than 1% of the total run time.
+						sprintf( pcWriteBuffer, "%s\t\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter );
+					}
+
+					pcWriteBuffer += strlen( ( char * ) pcWriteBuffer );
+				}
+			}
+
+			// The array is no longer needed, free the memory it consumes.
+			vPortFree( pxTaskStatusArray );
+		}
+	}
+	
+ */ +UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
void vTaskList( char *pcWriteBuffer, size_t bufSize);
//<< EST + * + * configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS must + * both be defined as 1 for this function to be available. See the + * configuration section of the FreeRTOS.org website for more information. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Lists all the current tasks, along with their current state and stack + * usage high water mark. + * + * Tasks are reported as blocked ('B'), ready ('R'), deleted ('D') or + * suspended ('S'). + * + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays task + * names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that might + * bloat the code size, use a lot of stack, and provide different results on + * different platforms. An alternative, tiny, third party, and limited + * functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly through a + * call to vTaskList(). + * + * @param pcWriteBuffer A buffer into which the above mentioned details + * will be written, in ASCII form. This buffer is assumed to be large + * enough to contain the generated report. Approximately 40 bytes per + * task should be sufficient. + * + * \defgroup vTaskList vTaskList + * \ingroup TaskUtils + */ +void vTaskList( char * pcWriteBuffer, size_t bufSize) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * task. h + *
void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize );
+ * + * configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS + * must both be defined as 1 for this function to be available. The application + * must also then provide definitions for + * portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() + * to configure a peripheral timer/counter and return the timers current count + * value respectively. The counter should be at least 10 times the frequency of + * the tick count. + * + * NOTE 1: This function will disable interrupts for its duration. It is + * not intended for normal application runtime use but as a debug aid. + * + * Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total + * accumulated execution time being stored for each task. The resolution + * of the accumulated time value depends on the frequency of the timer + * configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. + * Calling vTaskGetRunTimeStats() writes the total execution time of each + * task into a buffer, both as an absolute count value and as a percentage + * of the total system execution time. + * + * NOTE 2: + * + * This function is provided for convenience only, and is used by many of the + * demo applications. Do not consider it to be part of the scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that displays the + * amount of time each task has spent in the Running state in both absolute and + * percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library function + * that might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, and + * limited functionality implementation of sprintf() is provided in many of the + * FreeRTOS/Demo sub-directories in a file called printf-stdarg.c (note + * printf-stdarg.c does not provide a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() directly + * to get access to raw stats data, rather than indirectly through a call to + * vTaskGetRunTimeStats(). + * + * @param pcWriteBuffer A buffer into which the execution times will be + * written, in ASCII form. This buffer is assumed to be large enough to + * contain the generated report. Approximately 40 bytes per task should + * be sufficient. + * + * \defgroup vTaskGetRunTimeStats vTaskGetRunTimeStats + * \ingroup TaskUtils + */ +void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** +* task. h +*
TickType_t xTaskGetIdleRunTimeCounter( void );
+* +* configGENERATE_RUN_TIME_STATS and configUSE_STATS_FORMATTING_FUNCTIONS +* must both be defined as 1 for this function to be available. The application +* must also then provide definitions for +* portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and portGET_RUN_TIME_COUNTER_VALUE() +* to configure a peripheral timer/counter and return the timers current count +* value respectively. The counter should be at least 10 times the frequency of +* the tick count. +* +* Setting configGENERATE_RUN_TIME_STATS to 1 will result in a total +* accumulated execution time being stored for each task. The resolution +* of the accumulated time value depends on the frequency of the timer +* configured by the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() macro. +* While uxTaskGetSystemState() and vTaskGetRunTimeStats() writes the total +* execution time of each task into a buffer, xTaskGetIdleRunTimeCounter() +* returns the total execution time of just the idle task. +* +* @return The total run time of the idle task. This is the amount of time the +* idle task has actually been executing. The unit of time is dependent on the +* frequency configured using the portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() and +* portGET_RUN_TIME_COUNTER_VALUE() macros. +* +* \defgroup xTaskGetIdleRunTimeCounter xTaskGetIdleRunTimeCounter +* \ingroup TaskUtils +*/ +TickType_t xTaskGetIdleRunTimeCounter( void ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * pulPreviousNotificationValue - + * Can be used to pass out the subject task's notification value before any + * bits are modified by the notify function. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) PRIVILEGED_FUNCTION; +#define xTaskNotify( xTaskToNotify, ulValue, eAction ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL ) +#define xTaskNotifyAndQuery( xTaskToNotify, ulValue, eAction, pulPreviousNotifyValue ) xTaskGenericNotify( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotifyValue ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, BaseType_t *pxHigherPriorityTaskWoken );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * A version of xTaskNotify() that can be used from an interrupt service routine + * (ISR). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @param ulValue Data that can be sent with the notification. How the data is + * used depends on the value of the eAction parameter. + * + * @param eAction Specifies how the notification updates the task's notification + * value, if at all. Valid values for eAction are as follows: + * + * eSetBits - + * The task's notification value is bitwise ORed with ulValue. xTaskNofify() + * always returns pdPASS in this case. + * + * eIncrement - + * The task's notification value is incremented. ulValue is not used and + * xTaskNotify() always returns pdPASS in this case. + * + * eSetValueWithOverwrite - + * The task's notification value is set to the value of ulValue, even if the + * task being notified had not yet processed the previous notification (the + * task already had a notification pending). xTaskNotify() always returns + * pdPASS in this case. + * + * eSetValueWithoutOverwrite - + * If the task being notified did not already have a notification pending then + * the task's notification value is set to ulValue and xTaskNotify() will + * return pdPASS. If the task being notified already had a notification + * pending then no action is performed and pdFAIL is returned. + * + * eNoAction - + * The task receives a notification without its notification value being + * updated. ulValue is not used and xTaskNotify() always returns pdPASS in + * this case. + * + * @param pxHigherPriorityTaskWoken xTaskNotifyFromISR() will set + * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the + * task to which the notification was sent to leave the Blocked state, and the + * unblocked task has a priority higher than the currently running task. If + * xTaskNotifyFromISR() sets this value to pdTRUE then a context switch should + * be requested before the interrupt is exited. How a context switch is + * requested from an ISR is dependent on the port - see the documentation page + * for the port in use. + * + * @return Dependent on the value of eAction. See the description of the + * eAction parameter. + * + * \defgroup xTaskNotify xTaskNotify + * \ingroup TaskNotifications + */ +BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; +#define xTaskNotifyFromISR( xTaskToNotify, ulValue, eAction, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), NULL, ( pxHigherPriorityTaskWoken ) ) +#define xTaskNotifyAndQueryFromISR( xTaskToNotify, ulValue, eAction, pulPreviousNotificationValue, pxHigherPriorityTaskWoken ) xTaskGenericNotifyFromISR( ( xTaskToNotify ), ( ulValue ), ( eAction ), ( pulPreviousNotificationValue ), ( pxHigherPriorityTaskWoken ) ) + +/** + * task. h + *
BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * A notification sent to a task will remain pending until it is cleared by the + * task calling xTaskNotifyWait() or ulTaskNotifyTake(). If the task was + * already in the Blocked state to wait for a notification when the notification + * arrives then the task will automatically be removed from the Blocked state + * (unblocked) and the notification cleared. + * + * A task can use xTaskNotifyWait() to [optionally] block to wait for a + * notification to be pending, or ulTaskNotifyTake() to [optionally] block + * to wait for its notification value to have a non-zero value. The task does + * not consume any CPU time while it is in the Blocked state. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param ulBitsToClearOnEntry Bits that are set in ulBitsToClearOnEntry value + * will be cleared in the calling task's notification value before the task + * checks to see if any notifications are pending, and optionally blocks if no + * notifications are pending. Setting ulBitsToClearOnEntry to ULONG_MAX (if + * limits.h is included) or 0xffffffffUL (if limits.h is not included) will have + * the effect of resetting the task's notification value to 0. Setting + * ulBitsToClearOnEntry to 0 will leave the task's notification value unchanged. + * + * @param ulBitsToClearOnExit If a notification is pending or received before + * the calling task exits the xTaskNotifyWait() function then the task's + * notification value (see the xTaskNotify() API function) is passed out using + * the pulNotificationValue parameter. Then any bits that are set in + * ulBitsToClearOnExit will be cleared in the task's notification value (note + * *pulNotificationValue is set before any bits are cleared). Setting + * ulBitsToClearOnExit to ULONG_MAX (if limits.h is included) or 0xffffffffUL + * (if limits.h is not included) will have the effect of resetting the task's + * notification value to 0 before the function exits. Setting + * ulBitsToClearOnExit to 0 will leave the task's notification value unchanged + * when the function exits (in which case the value passed out in + * pulNotificationValue will match the task's notification value). + * + * @param pulNotificationValue Used to pass the task's notification value out + * of the function. Note the value passed out will not be effected by the + * clearing of any bits caused by ulBitsToClearOnExit being non-zero. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for a notification to be received, should a notification + * not already be pending when xTaskNotifyWait() was called. The task + * will not consume any processing time while it is in the Blocked state. This + * is specified in kernel ticks, the macro pdMS_TO_TICSK( value_in_ms ) can be + * used to convert a time specified in milliseconds to a time specified in + * ticks. + * + * @return If a notification was received (including notifications that were + * already pending when xTaskNotifyWait was called) then pdPASS is + * returned. Otherwise pdFAIL is returned. + * + * \defgroup xTaskNotifyWait xTaskNotifyWait + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyGive( TaskHandle_t xTaskToNotify );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro + * to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * xTaskNotifyGive() is a helper macro intended for use when task notifications + * are used as light weight and faster binary or counting semaphore equivalents. + * Actual FreeRTOS semaphores are given using the xSemaphoreGive() API function, + * the equivalent action that instead uses a task notification is + * xTaskNotifyGive(). + * + * When task notifications are being used as a binary or counting semaphore + * equivalent then the task being notified should wait for the notification + * using the ulTaskNotificationTake() API function rather than the + * xTaskNotifyWait() API function. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details. + * + * @param xTaskToNotify The handle of the task being notified. The handle to a + * task can be returned from the xTaskCreate() API function used to create the + * task, and the handle of the currently running task can be obtained by calling + * xTaskGetCurrentTaskHandle(). + * + * @return xTaskNotifyGive() is a macro that calls xTaskNotify() with the + * eAction parameter set to eIncrement - so pdPASS is always returned. + * + * \defgroup xTaskNotifyGive xTaskNotifyGive + * \ingroup TaskNotifications + */ +#define xTaskNotifyGive( xTaskToNotify ) xTaskGenericNotify( ( xTaskToNotify ), ( 0 ), eIncrement, NULL ) + +/** + * task. h + *
void vTaskNotifyGiveFromISR( TaskHandle_t xTaskHandle, BaseType_t *pxHigherPriorityTaskWoken );
+ *
+ * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this macro
+ * to be available.
+ *
+ * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private
+ * "notification value", which is a 32-bit unsigned integer (uint32_t).
+ *
+ * A version of xTaskNotifyGive() that can be called from an interrupt service
+ * routine (ISR).
+ *
+ * Events can be sent to a task using an intermediary object.  Examples of such
+ * objects are queues, semaphores, mutexes and event groups.  Task notifications
+ * are a method of sending an event directly to a task without the need for such
+ * an intermediary object.
+ *
+ * A notification sent to a task can optionally perform an action, such as
+ * update, overwrite or increment the task's notification value.  In that way
+ * task notifications can be used to send data to a task, or be used as light
+ * weight and fast binary or counting semaphores.
+ *
+ * vTaskNotifyGiveFromISR() is intended for use when task notifications are
+ * used as light weight and faster binary or counting semaphore equivalents.
+ * Actual FreeRTOS semaphores are given from an ISR using the
+ * xSemaphoreGiveFromISR() API function, the equivalent action that instead uses
+ * a task notification is vTaskNotifyGiveFromISR().
+ *
+ * When task notifications are being used as a binary or counting semaphore
+ * equivalent then the task being notified should wait for the notification
+ * using the ulTaskNotificationTake() API function rather than the
+ * xTaskNotifyWait() API function.
+ *
+ * See http://www.FreeRTOS.org/RTOS-task-notifications.html for more details.
+ *
+ * @param xTaskToNotify The handle of the task being notified.  The handle to a
+ * task can be returned from the xTaskCreate() API function used to create the
+ * task, and the handle of the currently running task can be obtained by calling
+ * xTaskGetCurrentTaskHandle().
+ *
+ * @param pxHigherPriorityTaskWoken  vTaskNotifyGiveFromISR() will set
+ * *pxHigherPriorityTaskWoken to pdTRUE if sending the notification caused the
+ * task to which the notification was sent to leave the Blocked state, and the
+ * unblocked task has a priority higher than the currently running task.  If
+ * vTaskNotifyGiveFromISR() sets this value to pdTRUE then a context switch
+ * should be requested before the interrupt is exited.  How a context switch is
+ * requested from an ISR is dependent on the port - see the documentation page
+ * for the port in use.
+ *
+ * \defgroup xTaskNotifyWait xTaskNotifyWait
+ * \ingroup TaskNotifications
+ */
+void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION;
+
+/**
+ * task. h
+ * 
uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait );
+ * + * configUSE_TASK_NOTIFICATIONS must be undefined or defined as 1 for this + * function to be available. + * + * When configUSE_TASK_NOTIFICATIONS is set to one each task has its own private + * "notification value", which is a 32-bit unsigned integer (uint32_t). + * + * Events can be sent to a task using an intermediary object. Examples of such + * objects are queues, semaphores, mutexes and event groups. Task notifications + * are a method of sending an event directly to a task without the need for such + * an intermediary object. + * + * A notification sent to a task can optionally perform an action, such as + * update, overwrite or increment the task's notification value. In that way + * task notifications can be used to send data to a task, or be used as light + * weight and fast binary or counting semaphores. + * + * ulTaskNotifyTake() is intended for use when a task notification is used as a + * faster and lighter weight binary or counting semaphore alternative. Actual + * FreeRTOS semaphores are taken using the xSemaphoreTake() API function, the + * equivalent action that instead uses a task notification is + * ulTaskNotifyTake(). + * + * When a task is using its notification value as a binary or counting semaphore + * other tasks should send notifications to it using the xTaskNotifyGive() + * macro, or xTaskNotify() function with the eAction parameter set to + * eIncrement. + * + * ulTaskNotifyTake() can either clear the task's notification value to + * zero on exit, in which case the notification value acts like a binary + * semaphore, or decrement the task's notification value on exit, in which case + * the notification value acts like a counting semaphore. + * + * A task can use ulTaskNotifyTake() to [optionally] block to wait for a + * the task's notification value to be non-zero. The task does not consume any + * CPU time while it is in the Blocked state. + * + * Where as xTaskNotifyWait() will return when a notification is pending, + * ulTaskNotifyTake() will return when the task's notification value is + * not zero. + * + * See http://www.FreeRTOS.org/RTOS-task-notifications.html for details. + * + * @param xClearCountOnExit if xClearCountOnExit is pdFALSE then the task's + * notification value is decremented when the function exits. In this way the + * notification value acts like a counting semaphore. If xClearCountOnExit is + * not pdFALSE then the task's notification value is cleared to zero when the + * function exits. In this way the notification value acts like a binary + * semaphore. + * + * @param xTicksToWait The maximum amount of time that the task should wait in + * the Blocked state for the task's notification value to be greater than zero, + * should the count not already be greater than zero when + * ulTaskNotifyTake() was called. The task will not consume any processing + * time while it is in the Blocked state. This is specified in kernel ticks, + * the macro pdMS_TO_TICSK( value_in_ms ) can be used to convert a time + * specified in milliseconds to a time specified in ticks. + * + * @return The task's notification count before it is either cleared to zero or + * decremented (see the xClearCountOnExit parameter). + * + * \defgroup ulTaskNotifyTake ulTaskNotifyTake + * \ingroup TaskNotifications + */ +uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * task. h + *
BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask );
+ * + * If the notification state of the task referenced by the handle xTask is + * eNotified, then set the task's notification state to eNotWaitingNotification. + * The task's notification value is not altered. Set xTask to NULL to clear the + * notification state of the calling task. + * + * @return pdTRUE if the task's notification state was set to + * eNotWaitingNotification, otherwise pdFALSE. + * \defgroup xTaskNotifyStateClear xTaskNotifyStateClear + * \ingroup TaskNotifications + */ +BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ); + +/*----------------------------------------------------------- + * SCHEDULER INTERNALS AVAILABLE FOR PORTING PURPOSES + *----------------------------------------------------------*/ + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Called from the real time kernel tick (either preemptive or cooperative), + * this increments the tick count and checks if any tasks that are blocked + * for a finite period required removing from a blocked list and placing on + * a ready list. If a non-zero value is returned then a context switch is + * required because either: + * + A task was removed from a blocked list because its timeout had expired, + * or + * + Time slicing is in use and there is a task of equal priority to the + * currently running task. + */ +BaseType_t xTaskIncrementTick( void ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes the calling task from the ready list and places it both + * on the list of tasks waiting for a particular event, and the + * list of delayed tasks. The task will be removed from both lists + * and replaced on the ready list should either the event occur (and + * there be no higher priority tasks waiting on the same event) or + * the delay period expires. + * + * The 'unordered' version replaces the event list item value with the + * xItemValue value, and inserts the list item at the end of the list. + * + * The 'ordered' version uses the existing event list item value (which is the + * owning tasks priority) to insert the list item into the event list is task + * priority order. + * + * @param pxEventList The list containing tasks that are blocked waiting + * for the event to occur. + * + * @param xItemValue The item value to use for the event list item when the + * event list is not ordered by task priority. + * + * @param xTicksToWait The maximum amount of time that the task should wait + * for the event to occur. This is specified in kernel ticks,the constant + * portTICK_PERIOD_MS can be used to convert kernel ticks into a real time + * period. + */ +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * This function performs nearly the same function as vTaskPlaceOnEventList(). + * The difference being that this function does not permit tasks to block + * indefinitely, whereas vTaskPlaceOnEventList() does. + * + */ +void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS AN + * INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED. + * + * Removes a task from both the specified event list and the list of blocked + * tasks, and places it on a ready queue. + * + * xTaskRemoveFromEventList()/vTaskRemoveFromUnorderedEventList() will be called + * if either an event occurs to unblock a task, or the block timeout period + * expires. + * + * xTaskRemoveFromEventList() is used when the event list is in task priority + * order. It removes the list item from the head of the event list as that will + * have the highest priority owning task of all the tasks on the event list. + * vTaskRemoveFromUnorderedEventList() is used when the event list is not + * ordered and the event list items hold something other than the owning tasks + * priority. In this case the event list item value is updated to the value + * passed in the xItemValue parameter. + * + * @return pdTRUE if the task being removed has a higher priority than the task + * making the call, otherwise pdFALSE. + */ +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) PRIVILEGED_FUNCTION; +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) PRIVILEGED_FUNCTION; + +/* + * THIS FUNCTION MUST NOT BE USED FROM APPLICATION CODE. IT IS ONLY + * INTENDED FOR USE WHEN IMPLEMENTING A PORT OF THE SCHEDULER AND IS + * AN INTERFACE WHICH IS FOR THE EXCLUSIVE USE OF THE SCHEDULER. + * + * Sets the pointer to the current TCB to the TCB of the highest priority task + * that is ready to run. + */ +#ifdef __GNUC__ /* << EST: 'used' attribute need for LTO (Link Time Optimization) */ + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION __attribute__((used)); +#else + void vTaskSwitchContext( void ) PRIVILEGED_FUNCTION; +#endif + +/* + * THESE FUNCTIONS MUST NOT BE USED FROM APPLICATION CODE. THEY ARE USED BY + * THE EVENT BITS MODULE. + */ +TickType_t uxTaskResetEventItemValue( void ) PRIVILEGED_FUNCTION; + +/* + * Return the handle of the calling task. + */ +TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION; + +/* + * Capture the current time status for future reference. + */ +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + +/* + * Compare the time status now with that previously captured to see if the + * timeout has expired. + */ +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) PRIVILEGED_FUNCTION; + +/* + * Shortcut used by the queue implementation to prevent unnecessary call to + * taskYIELD(); + */ +void vTaskMissedYield( void ) PRIVILEGED_FUNCTION; + +/* + * Returns the scheduler state as taskSCHEDULER_RUNNING, + * taskSCHEDULER_NOT_STARTED or taskSCHEDULER_SUSPENDED. + */ +BaseType_t xTaskGetSchedulerState( void ) PRIVILEGED_FUNCTION; + +/* + * Raises the priority of the mutex holder to that of the calling task should + * the mutex holder have a priority less than the calling task. + */ +BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * Set the priority of a task back to its proper priority in the case that it + * inherited a higher priority while it was holding a semaphore. + */ +BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGED_FUNCTION; + +/* + * If a higher priority task attempting to obtain a mutex caused a lower + * priority task to inherit the higher priority task's priority - but the higher + * priority task then timed out without obtaining the mutex, then the lower + * priority task will disinherit the priority again - but only down as far as + * the highest priority task that is still waiting for the mutex (if there were + * more than one task waiting for the mutex). + */ +void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) PRIVILEGED_FUNCTION; + +/* + * Get the uxTCBNumber assigned to the task referenced by the xTask parameter. + */ +UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +/* + * Set the uxTaskNumber of the task referenced by the xTask parameter to + * uxHandle. + */ +void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * If tickless mode is being used, or a low power mode is implemented, then + * the tick interrupt will not execute during idle periods. When this is the + * case, the tick count value maintained by the scheduler needs to be kept up + * to date with the actual execution time by being skipped forward by a time + * equal to the idle period. + */ +void vTaskStepTick( const TickType_t xTicksToJump ) PRIVILEGED_FUNCTION; + +/* + * Only available when configUSE_TICKLESS_IDLE is set to 1. + * Provided for use within portSUPPRESS_TICKS_AND_SLEEP() to allow the port + * specific sleep function to determine if it is ok to proceed with the sleep, + * and if it is ok to proceed, if it is ok to sleep indefinitely. + * + * This function is necessary because portSUPPRESS_TICKS_AND_SLEEP() is only + * called with the scheduler suspended, not from within a critical section. It + * is therefore possible for an interrupt to request a context switch between + * portSUPPRESS_TICKS_AND_SLEEP() and the low power mode actually being + * entered. eTaskConfirmSleepModeStatus() should be called from a short + * critical section between the timer being stopped and the sleep mode being + * entered to ensure it is ok to proceed into the sleep mode. + */ +eSleepModeStatus eTaskConfirmSleepModeStatus( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Increment the mutex held count when a mutex is + * taken and return the handle of the task that has taken the mutex. + */ +TaskHandle_t pvTaskIncrementMutexHeldCount( void ) PRIVILEGED_FUNCTION; + +/* + * For internal use only. Same as vTaskSetTimeOutState(), but without a critial + * section. + */ +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) PRIVILEGED_FUNCTION; + + +#if 1 /* << EST */ +/*! + \brief Collects all the task handles present in the system and stores them in to an array of task handles. + \param pxTaskHandleArray Pointer to an array of task handles where the handles will be stored. + \param xNofTaskHandlesInArray Number of task handles in the array. + \return Number of task handles stored in array. + */ +UBaseType_t xGetTaskHandles(TaskHandle_t pxTaskHandleArray[], UBaseType_t xNofTaskHandlesInArray); + +/*! + * \brief Returns stack information about the given task handle. + * \param xTask Task handle + * \param ppxStart Returns the start of the stack area. This is the 'bottom' of the stack, with the stack pointer growing to the 'top'. + * \param ppxEnd Returns the end of the stack area. This is the 'top' of the stack where the stack pointer grows to. + * \param ppxTopOfStack Returns the current stack pointer value. + * \param pucStaticallyAllocated 0, if statically allocated, !=0 if allocated dynamically + */ +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated); + +/*! + * \brief Return a pointer to the task start + * \param xTask Task handle + */ +uint8_t* pxTaskGetStackStart(TaskHandle_t xTask); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* INC_TASK_H */ + + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/tasks.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/tasks.c new file mode 100644 index 0000000..d80c87e --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/tasks.c @@ -0,0 +1,5474 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "timers.h" +#include "stack_macros.h" + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) ) +#include "UTIL1.h" /* interface to utility because used for safe string routines */ /* << EST */ +#endif + +#if (configCOMPILER == configCOMPILER_ARM_IAR) /* << EST: suppress warnings for IAR */ +#pragma diag_suppress=pa082 /* Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement */ +#endif +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750 !e9021. */ + +/* Set configUSE_STATS_FORMATTING_FUNCTIONS to 2 to include the stats formatting +functions but without including stdio.h here. */ +#if ( configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) + /* At the bottom of this file are two optional functions that can be used + to generate human readable text from the raw data generated by the + uxTaskGetSystemState() function. Note the formatting functions are provided + for convenience only, and are NOT considered part of the kernel. */ + #include +#endif /* configUSE_STATS_FORMATTING_FUNCTIONS == 1 ) */ + +#if( configUSE_PREEMPTION == 0 ) + /* If the cooperative scheduler is being used then a yield should not be + performed just because a higher priority task has been woken. */ + #define taskYIELD_IF_USING_PREEMPTION() +#else + #define taskYIELD_IF_USING_PREEMPTION() portYIELD_WITHIN_API() +#endif + +/* Values that can be assigned to the ucNotifyState member of the TCB. */ +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) + +/* + * The value used to fill the stack of a task when the task is created. This + * is used purely for checking the high water mark for tasks. + */ +#define tskSTACK_FILL_BYTE ( 0xa5U ) + +/* Bits used to recored how a task's stack and TCB were allocated. */ +#define tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 0 ) +#define tskSTATICALLY_ALLOCATED_STACK_ONLY ( ( uint8_t ) 1 ) +#define tskSTATICALLY_ALLOCATED_STACK_AND_TCB ( ( uint8_t ) 2 ) + +/* If any of the following are set then task stacks are filled with a known +value so the high water mark can be determined. If none of the following are +set then don't fill the stack so there is no unnecessary dependency on memset. */ +#if( ( configCHECK_FOR_STACK_OVERFLOW > 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 1 +#else + #define tskSET_NEW_STACKS_TO_KNOWN_VALUE 0 +#endif + +/* + * Macros used by vListTask to indicate which state a task is in. + */ +#define tskRUNNING_CHAR ( 'X' ) +#define tskBLOCKED_CHAR ( 'B' ) +#define tskREADY_CHAR ( 'R' ) +#define tskDELETED_CHAR ( 'D' ) +#define tskSUSPENDED_CHAR ( 'S' ) + +/* + * Some kernel aware debuggers require the data the debugger needs access to be + * global, rather than file scope. + */ +#ifdef portREMOVE_STATIC_QUALIFIER + #define static +#endif + +/* The name allocated to the Idle task. This can be overridden by defining +configIDLE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configIDLE_TASK_NAME + #define configIDLE_TASK_NAME "IDLE" +#endif + +#if ( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 0 then task selection is + performed in a generic way that is not optimised to any particular + microcontroller architecture. */ + + /* uxTopReadyPriority holds the priority of the highest priority ready + state task. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) \ + { \ + if( ( uxPriority ) > uxTopReadyPriority ) \ + { \ + uxTopReadyPriority = ( uxPriority ); \ + } \ + } /* taskRECORD_READY_PRIORITY */ + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority = uxTopReadyPriority; \ + \ + /* Find the highest priority queue that contains ready tasks. */ \ + while( listLIST_IS_EMPTY( &( pxReadyTasksLists[ uxTopPriority ] ) ) ) \ + { \ + configASSERT( uxTopPriority ); \ + --uxTopPriority; \ + } \ + \ + /* listGET_OWNER_OF_NEXT_ENTRY indexes through the list, so the tasks of \ + the same priority get an equal share of the processor time. */ \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + uxTopReadyPriority = uxTopPriority; \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK */ + + /*-----------------------------------------------------------*/ + + /* Define away taskRESET_READY_PRIORITY() and portRESET_READY_PRIORITY() as + they are only required when a port optimised method of task selection is + being used. */ + #define taskRESET_READY_PRIORITY( uxPriority ) + #define portRESET_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + +#else /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + + /* If configUSE_PORT_OPTIMISED_TASK_SELECTION is 1 then task selection is + performed in a way that is tailored to the particular microcontroller + architecture being used. */ + + /* A port optimised version is provided. Call the port defined macros. */ + #define taskRECORD_READY_PRIORITY( uxPriority ) portRECORD_READY_PRIORITY( uxPriority, uxTopReadyPriority ) + + /*-----------------------------------------------------------*/ + + #define taskSELECT_HIGHEST_PRIORITY_TASK() \ + { \ + UBaseType_t uxTopPriority; \ + \ + /* Find the highest priority list that contains ready tasks. */ \ + portGET_HIGHEST_PRIORITY( uxTopPriority, uxTopReadyPriority ); \ + configASSERT( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ uxTopPriority ] ) ) > 0 ); \ + listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopPriority ] ) ); \ + } /* taskSELECT_HIGHEST_PRIORITY_TASK() */ + + /*-----------------------------------------------------------*/ + + /* A port optimised version is provided, call it only if the TCB being reset + is being referenced from a ready list. If it is referenced from a delayed + or suspended list then it won't be in a ready list. */ + #define taskRESET_READY_PRIORITY( uxPriority ) \ + { \ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ ( uxPriority ) ] ) ) == ( UBaseType_t ) 0 ) \ + { \ + portRESET_READY_PRIORITY( ( uxPriority ), ( uxTopReadyPriority ) ); \ + } \ + } + +#endif /* configUSE_PORT_OPTIMISED_TASK_SELECTION */ + +/*-----------------------------------------------------------*/ + +/* pxDelayedTaskList and pxOverflowDelayedTaskList are switched when the tick +count overflows. */ +#define taskSWITCH_DELAYED_LISTS() \ +{ \ + List_t *pxTemp; \ + \ + /* The delayed tasks list should be empty when the lists are switched. */ \ + configASSERT( ( listLIST_IS_EMPTY( pxDelayedTaskList ) ) ); \ + \ + pxTemp = pxDelayedTaskList; \ + pxDelayedTaskList = pxOverflowDelayedTaskList; \ + pxOverflowDelayedTaskList = pxTemp; \ + xNumOfOverflows++; \ + prvResetNextTaskUnblockTime(); \ +} + +/*-----------------------------------------------------------*/ + +/* + * Place the task represented by pxTCB into the appropriate ready list for + * the task. It is inserted at the end of the list. + */ +#define prvAddTaskToReadyList( pxTCB ) \ + traceMOVED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ); \ + tracePOST_MOVED_TASK_TO_READY_STATE( pxTCB ) +/*-----------------------------------------------------------*/ + +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ +/* + * Place the task represented by pxTCB which has been in a ready list before + * into the appropriate ready list for the task. + * It is inserted at the end of the list. + */ +#define prvReAddTaskToReadyList( pxTCB ) \ + traceREADDED_TASK_TO_READY_STATE( pxTCB ); \ + taskRECORD_READY_PRIORITY( ( pxTCB )->uxPriority ); \ + vListInsertEnd( &( pxReadyTasksLists[ ( pxTCB )->uxPriority ] ), &( ( pxTCB )->xStateListItem ) ) + +#endif /* configUSE_SEGGER_SYSTEM_VIEWER_HOOKS */ /* << EST */ + +/* + * Several functions take an TaskHandle_t parameter that can optionally be NULL, + * where NULL is used to indicate that the handle of the currently executing + * task should be used in place of the parameter. This macro simply checks to + * see if the parameter is NULL and returns a pointer to the appropriate TCB. + */ +#define prvGetTCBFromHandle( pxHandle ) ( ( ( pxHandle ) == NULL ) ? pxCurrentTCB : ( pxHandle ) ) + +/* The item value of the event list item is normally used to hold the priority +of the task to which it belongs (coded to allow it to be held in reverse +priority order). However, it is occasionally borrowed for other purposes. It +is important its value is not updated due to a task priority change while it is +being used for another purpose. The following bit definition is used to inform +the scheduler that the value should not be changed - in which case it is the +responsibility of whichever module is using the value to ensure it gets set back +to its original value when it is released. */ +#if( configUSE_16_BIT_TICKS == 1 ) + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x8000U +#else + #define taskEVENT_LIST_ITEM_VALUE_IN_USE 0x80000000UL +#endif + +/* + * Task control block. A task control block (TCB) is allocated for each task, + * and stores task state information, including a pointer to the task's context + * (the task's run time environment, including register values) + */ +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + volatile StackType_t *pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t *pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t *pxEndOfStack; /*< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void *pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + /* Allocate a Newlib reent structure that is specific to this task. + Note Newlib support has been included by popular demand, but is not + used by the FreeRTOS maintainers themselves. FreeRTOS is not + responsible for resulting newlib operation. User must be familiar with + newlib and must provide system-wide implementations of the necessary + stubs. Be warned that (at the time of writing) the current newlib design + implements a system-wide malloc() that must be provided with locks. */ + struct _reent xNewLib_reent; + #endif + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue; + volatile uint8_t ucNotifyState; + #endif + + /* See the comments in FreeRTOS.h with the definition of + tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif + +} tskTCB; + +/* The old tskTCB name is maintained above then typedefed to the new TCB_t name +below to enable the use of older kernel aware debuggers. */ +typedef tskTCB TCB_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ +PRIVILEGED_DATA TCB_t * volatile pxCurrentTCB = NULL; + +/* Lists for ready and blocked tasks. -------------------- +xDelayedTaskList1 and xDelayedTaskList2 could be move to function scople but +doing so breaks some kernel aware debuggers and debuggers that rely on removing +the static qualifier. */ +#if configLTO_HELPER + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA /*static*/ List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA /*static*/ List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA /*static*/ List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#else + PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ];/*< Prioritised ready tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList1; /*< Delayed tasks. */ + PRIVILEGED_DATA static List_t xDelayedTaskList2; /*< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList; /*< Points to the delayed task list currently being used. */ + PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList; /*< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */ + PRIVILEGED_DATA static List_t xPendingReadyList; /*< Tasks that have been readied while the scheduler was suspended. They will be moved to the ready list when the scheduler is resumed. */ +#endif + +#if( INCLUDE_vTaskDelete == 1 ) + +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#else + PRIVILEGED_DATA static List_t xTasksWaitingTermination; /*< Tasks that have been deleted - but their memory not yet freed. */ +#endif + PRIVILEGED_DATA static volatile UBaseType_t uxDeletedTasksWaitingCleanUp = ( UBaseType_t ) 0U; + +#endif + +#if ( INCLUDE_vTaskSuspend == 1 ) +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#else + PRIVILEGED_DATA static List_t xSuspendedTaskList; /*< Tasks that are currently suspended. */ +#endif +#endif + +/* Global POSIX errno. Its value is changed upon context switching to match +the errno of the currently running task. */ +#if ( configUSE_POSIX_ERRNO == 1 ) + int FreeRTOS_errno = 0; +#endif + +/* Other file private variables. --------------------------------*/ +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; +#endif +PRIVILEGED_DATA static volatile TickType_t xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; +#if configLTO_HELPER /* << EST */ + /* If using -lto (Link Time Optimization), the linker might replace/remove the names of the following variables. + * If using a FreeRTOS Kernel aware debugger (e.g. Segger FreeRTOS task aware plugin), then the debugger won't be able to see the symbols and will fail. + * Therefore (more as of a hack) the symbols are defined with external linkage, even if not used from other modules. + * See https://mcuoneclipse.com/2017/07/27/troubleshooting-tips-for-freertos-thread-aware-debugging-in-eclipse/ + */ + PRIVILEGED_DATA /*static*/ volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA /*static*/ volatile BaseType_t xSchedulerRunning = pdFALSE; +#else + PRIVILEGED_DATA static volatile UBaseType_t uxTopReadyPriority = tskIDLE_PRIORITY; + PRIVILEGED_DATA static volatile BaseType_t xSchedulerRunning = pdFALSE; +#endif +PRIVILEGED_DATA static volatile UBaseType_t uxPendedTicks = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile BaseType_t xYieldPending = pdFALSE; +PRIVILEGED_DATA static volatile BaseType_t xNumOfOverflows = ( BaseType_t ) 0; +PRIVILEGED_DATA static UBaseType_t uxTaskNumber = ( UBaseType_t ) 0U; +PRIVILEGED_DATA static volatile TickType_t xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ +PRIVILEGED_DATA static TaskHandle_t xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + +/* Context switches are held pending while the scheduler is suspended. Also, +interrupts must not manipulate the xStateListItem of a TCB, or any of the +lists the xStateListItem can be referenced from, if the scheduler is suspended. +If an interrupt needs to unblock a task while the scheduler is suspended then it +moves the task's event list item into the xPendingReadyList, ready for the +kernel to move the task from the pending ready list into the real ready list +when the scheduler is unsuspended. The pending ready list itself can only be +accessed from a critical section. */ +PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended = ( UBaseType_t ) pdFALSE; + +#if ( configGENERATE_RUN_TIME_STATS == 1 ) + + /* Do not move these variables to function scope as doing so prevents the + code working with debuggers that need to remove the static qualifier. */ + PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */ +#if 1 /* << EST: prevent optimizations and removal of the following variable with -O1, -O2 or -O3, as used by NXP TAD */ + PRIVILEGED_DATA static + #ifdef __GNUC__ + __attribute__((used)) + #endif + uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#else + PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */ +#endif + +#endif + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +/* Callback function prototypes. --------------------------*/ +#if( configCHECK_FOR_STACK_OVERFLOW > 0 ) +#if 1 /* << EST */ + extern void configCHECK_FOR_STACK_OVERFLOW_NAME( TaskHandle_t xTask, char *pcTaskName ); +#else + extern void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName ); +#endif +#endif + +#if( configUSE_TICK_HOOK > 0 ) + + extern void vApplicationTickHook( void ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + extern void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize ); /*lint !e526 Symbol not defined as it is an application callback. */ + +#endif + +/* File private functions. --------------------------------*/ + +/** + * Utility task that simply returns pdTRUE if the task referenced by xTask is + * currently in the Suspended state, or pdFALSE if the task referenced by xTask + * is in any other state. + */ +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) PRIVILEGED_FUNCTION; + +#endif /* INCLUDE_vTaskSuspend */ + +/* + * Utility to ready all the lists used by the scheduler. This is called + * automatically upon the creation of the first task. + */ +static void prvInitialiseTaskLists( void ) PRIVILEGED_FUNCTION; + +/* + * The idle task, which as all tasks is implemented as a never ending loop. + * The idle task is automatically created and added to the ready lists upon + * creation of the first user task. + * + * The portTASK_FUNCTION_PROTO() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION_PROTO( prvIdleTask, pvParameters ); + +/* + * Utility to free all memory allocated by the scheduler to hold a TCB, + * including the stack pointed to by the TCB. + * + * This does not free memory allocated by the task itself (i.e. memory + * allocated by calls to pvPortMalloc from within the tasks application code). + */ +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Used only by the idle task. This checks to see if anything has been placed + * in the list of tasks waiting to be deleted. If so the task is cleaned up + * and its TCB deleted. + */ +static void prvCheckTasksWaitingTermination( void ) PRIVILEGED_FUNCTION; + +/* + * The currently executing task is entering the Blocked state. Add the task to + * either the current or the overflow delayed task list. + */ +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) PRIVILEGED_FUNCTION; + +/* + * Fills an TaskStatus_t structure with information on each task that is + * referenced from the pxList list (which may be a ready list, a delayed list, + * a suspended list, etc.). + * + * THIS FUNCTION IS INTENDED FOR DEBUGGING ONLY, AND SHOULD NOT BE CALLED FROM + * NORMAL APPLICATION CODE. + */ +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Searches pxList for a task with name pcNameToQuery - returning a handle to + * the task if it is found, or NULL if the task is not found. + */ +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) PRIVILEGED_FUNCTION; + +#endif + +/* + * When a task is created, the stack of the task is filled with a known value. + * This function determines the 'high water mark' of the task stack by + * determining how much of the stack remains at the original preset value. + */ +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Return the amount of time, in ticks, that will pass before the kernel will + * next move a task from the Blocked state to the Running state. + * + * This conditional compilation should use inequality to 0, not equality to 1. + * This is to ensure portSUPPRESS_TICKS_AND_SLEEP() can be called when user + * defined low power mode implementations require configUSE_TICKLESS_IDLE to be + * set to a value other than 1. + */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) PRIVILEGED_FUNCTION; + +#endif + +/* + * Set xNextTaskUnblockTime to the time at which the next Blocked state task + * will exit the Blocked state. + */ +static void prvResetNextTaskUnblockTime( void ); + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) + + /* + * Helper function used to pad task names with spaces when printing out + * human readable tables of task information. + */ +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) PRIVILEGED_FUNCTION; +#endif + +#endif +/* + * Called after a Task_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) PRIVILEGED_FUNCTION; + +/* + * Called after a new task has been created and initialised to place the task + * under the control of the scheduler. + */ +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION; + +/* + * freertos_tasks_c_additions_init() should only be called if the user definable + * macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is the only macro + * called by the function. + */ +#ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + + static void freertos_tasks_c_additions_init( void ) PRIVILEGED_FUNCTION; + +#endif + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + StackType_t * const puxStackBuffer, + StaticTask_t * const pxTaskBuffer ) + { + TCB_t *pxNewTCB; + TaskHandle_t xReturn; + + configASSERT( puxStackBuffer != NULL ); + configASSERT( pxTaskBuffer != NULL ); + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTask_t equals the size of the real task + structure. */ + volatile size_t xSize = sizeof( StaticTask_t ); + configASSERT( xSize == sizeof( TCB_t ) ); + ( void ) xSize; /* Prevent lint warning when configASSERT() is not used. */ + } + #endif /* configASSERT_DEFINED */ + + + if( ( pxTaskBuffer != NULL ) && ( puxStackBuffer != NULL ) ) + { + /* The memory used for the task's TCB and stack are passed into this + function - use them. */ + pxNewTCB = ( TCB_t * ) pxTaskBuffer; /*lint !e740 !e9087 Unusual cast is ok as the structures are designed to have the same alignment, and the size is checked by an assert. */ + pxNewTCB->pxStack = ( StackType_t * ) puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ulStackDepth, pvParameters, uxPriority, &xReturn, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + } + else + { + xReturn = NULL; + } + + return xReturn; + } + +#endif /* SUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer != NULL ); + configASSERT( pxTaskDefinition->pxTaskBuffer != NULL ); + + if( ( pxTaskDefinition->puxStackBuffer != NULL ) && ( pxTaskDefinition->pxTaskBuffer != NULL ) ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pxTaskDefinition->pxTaskBuffer; + + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note this + task was created statically in case the task is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + + return xReturn; + } + +#endif /* ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) */ +/*-----------------------------------------------------------*/ + +#if( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + + configASSERT( pxTaskDefinition->puxStackBuffer ); + + if( pxTaskDefinition->puxStackBuffer != NULL ) + { + /* Allocate space for the TCB. Where the memory comes from depends + on the implementation of the port malloc function and whether or + not static allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxTaskDefinition->puxStackBuffer; + + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + { + /* Tasks can be created statically or dynamically, so note + this task had a statically allocated stack in case it is + later deleted. The TCB was allocated dynamically. */ + pxNewTCB->ucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_ONLY; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskDefinition->pvTaskCode, + pxTaskDefinition->pcName, + ( uint32_t ) pxTaskDefinition->usStackDepth, + pxTaskDefinition->pvParameters, + pxTaskDefinition->uxPriority, + pxCreatedTask, pxNewTCB, + pxTaskDefinition->xRegions ); + + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + } + + return xReturn; + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const configSTACK_DEPTH_TYPE usStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask ) + { + TCB_t *pxNewTCB; + BaseType_t xReturn; + + /* If the stack grows down then allocate the stack then the TCB so the stack + does not grow into the TCB. Likewise if the stack grows up then allocate + the TCB then the stack. */ + #if( portSTACK_GROWTH > 0 ) + { + /* Allocate space for the TCB. Where the memory comes from depends on + the implementation of the port malloc function and whether or not static + allocation is being used. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); + + if( pxNewTCB != NULL ) + { + /* Allocate space for the stack used by the task being created. + The base of the stack memory stored in the TCB so the task can + be deleted later if required. */ + pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + if( pxNewTCB->pxStack == NULL ) + { + /* Could not allocate the stack. Delete the allocated TCB. */ + vPortFree( pxNewTCB ); + pxNewTCB = NULL; + } + } + } + #else /* portSTACK_GROWTH */ + { + StackType_t *pxStack; + + /* Allocate space for the stack used by the task being created. */ + pxStack = pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation is the stack. */ + + if( pxStack != NULL ) + { + /* Allocate space for the TCB. */ + pxNewTCB = ( TCB_t * ) pvPortMalloc( sizeof( TCB_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of TCB_t is always a pointer to the task's stack. */ + + if( pxNewTCB != NULL ) + { + /* Store the stack location in the TCB. */ + pxNewTCB->pxStack = pxStack; + } + else + { + /* The stack cannot be used as the TCB was not created. Free + it again. */ + vPortFree( pxStack ); + } + } + else + { + pxNewTCB = NULL; + } + } + #endif /* portSTACK_GROWTH */ + + if( pxNewTCB != NULL ) + { + #if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e9029 !e731 Macro has been consolidated for readability reasons. */ + { + /* Tasks can be created statically or dynamically, so note this + task was created dynamically in case it is later deleted. */ + pxNewTCB->ucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; + } + #endif /* tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE */ + + prvInitialiseNewTask( pxTaskCode, pcName, ( uint32_t ) usStackDepth, pvParameters, uxPriority, pxCreatedTask, pxNewTCB, NULL ); + prvAddNewTaskToReadyList( pxNewTCB ); + xReturn = pdPASS; + } + else + { + xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY; + } + + return xReturn; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTask( TaskFunction_t pxTaskCode, + const char * const pcName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const uint32_t ulStackDepth, + void * const pvParameters, + UBaseType_t uxPriority, + TaskHandle_t * const pxCreatedTask, + TCB_t *pxNewTCB, + const MemoryRegion_t * const xRegions ) +{ +StackType_t *pxTopOfStack; +UBaseType_t x; + + #if( portUSING_MPU_WRAPPERS == 1 ) + /* Should the task be created in privileged mode? */ + BaseType_t xRunPrivileged; + if( ( uxPriority & portPRIVILEGE_BIT ) != 0U ) + { + xRunPrivileged = pdTRUE; + } + else + { + xRunPrivileged = pdFALSE; + } + uxPriority &= ~portPRIVILEGE_BIT; + #endif /* portUSING_MPU_WRAPPERS == 1 */ + + /* Avoid dependency on memset() if it is not required. */ + #if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 ) + { + /* Fill the stack with a known value to assist debugging. */ + ( void ) memset( pxNewTCB->pxStack, ( int ) tskSTACK_FILL_BYTE, ( size_t ) ulStackDepth * sizeof( StackType_t ) ); + } + #endif /* tskSET_NEW_STACKS_TO_KNOWN_VALUE */ + + /* Calculate the top of stack address. This depends on whether the stack + grows from high memory to low (as per the 80x86) or vice versa. + portSTACK_GROWTH is used to make the result positive or negative as required + by the port. */ + #if( portSTACK_GROWTH < 0 ) + { + pxTopOfStack = &( pxNewTCB->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); /*lint !e923 !e9033 !e9078 MISRA exception. Avoiding casts between pointers and integers is not practical. Size differences accounted for using portPOINTER_SIZE_TYPE type. Checked by assert(). */ + + /* Check the alignment of the calculated top of stack is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + #if( configRECORD_STACK_HIGH_ADDRESS == 1 ) + { + /* Also record the stack's high address, which may assist + debugging. */ + pxNewTCB->pxEndOfStack = pxTopOfStack; + } + #endif /* configRECORD_STACK_HIGH_ADDRESS */ + } + #else /* portSTACK_GROWTH */ + { + pxTopOfStack = pxNewTCB->pxStack; + + /* Check the alignment of the stack buffer is correct. */ + configASSERT( ( ( ( portPOINTER_SIZE_TYPE ) pxNewTCB->pxStack & ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) == 0UL ) ); + + /* The other extreme of the stack space is required if stack checking is + performed. */ + pxNewTCB->pxEndOfStack = pxNewTCB->pxStack + ( ulStackDepth - ( uint32_t ) 1 ); + } + #endif /* portSTACK_GROWTH */ + + /* Store the task name in the TCB. */ + if( pcName != NULL ) + { + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + pxNewTCB->pcTaskName[ x ] = pcName[ x ]; + + /* Don't copy all configMAX_TASK_NAME_LEN if the string is shorter than + configMAX_TASK_NAME_LEN characters just in case the memory after the + string is not accessible (extremely unlikely). */ + if( pcName[ x ] == ( char ) 0x00 ) + { + break; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Ensure the name string is terminated in the case that the string length + was greater or equal to configMAX_TASK_NAME_LEN. */ + pxNewTCB->pcTaskName[ configMAX_TASK_NAME_LEN - 1 ] = '\0'; + } + else + { + /* The task has not been given a name, so just ensure there is a NULL + terminator when it is read out. */ + pxNewTCB->pcTaskName[ 0 ] = 0x00; + } + + /* This is used as an array index so must ensure it's not too large. First + remove the privilege bit if one is present. */ + if( uxPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxNewTCB->uxPriority = uxPriority; + #if ( configUSE_MUTEXES == 1 ) + { + pxNewTCB->uxBasePriority = uxPriority; + pxNewTCB->uxMutexesHeld = 0; + } + #endif /* configUSE_MUTEXES */ + + vListInitialiseItem( &( pxNewTCB->xStateListItem ) ); + vListInitialiseItem( &( pxNewTCB->xEventListItem ) ); + + /* Set the pxNewTCB as a link back from the ListItem_t. This is so we can get + back to the containing TCB from a generic item in a list. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xStateListItem ), pxNewTCB ); + + /* Event lists are always in priority order. */ + listSET_LIST_ITEM_VALUE( &( pxNewTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + listSET_LIST_ITEM_OWNER( &( pxNewTCB->xEventListItem ), pxNewTCB ); + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + { + pxNewTCB->uxCriticalNesting = ( UBaseType_t ) 0U; + } + #endif /* portCRITICAL_NESTING_IN_TCB */ + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + { + pxNewTCB->pxTaskTag = NULL; + } + #endif /* configUSE_APPLICATION_TASK_TAG */ + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxNewTCB->ulRunTimeCounter = 0UL; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + { + vPortStoreTaskMPUSettings( &( pxNewTCB->xMPUSettings ), xRegions, pxNewTCB->pxStack, ulStackDepth ); + } + #else + { + /* Avoid compiler warning about unreferenced parameter. */ + ( void ) xRegions; + } + #endif + + #if( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + { + for( x = 0; x < ( UBaseType_t ) configNUM_THREAD_LOCAL_STORAGE_POINTERS; x++ ) + { + pxNewTCB->pvThreadLocalStoragePointers[ x ] = NULL; + } + } + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + { + pxNewTCB->ulNotifiedValue = 0; + pxNewTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Initialise this task's Newlib reent structure. */ + _REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) ); + } + #endif + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + pxNewTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Initialize the TCB stack to look as if the task was already running, + but had been interrupted by the scheduler. The return address is set + to the start of the task function. Once the stack has been initialised + the top of stack variable is updated. */ + #if( portUSING_MPU_WRAPPERS == 1 ) + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters, xRunPrivileged ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #else /* portUSING_MPU_WRAPPERS */ + { + /* If the port has capability to detect stack overflow, + pass the stack end address to the stack initialization + function as well. */ + #if( portHAS_STACK_OVERFLOW_CHECKING == 1 ) + { + #if( portSTACK_GROWTH < 0 ) + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxStack, pxTaskCode, pvParameters ); + } + #else /* portSTACK_GROWTH */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxNewTCB->pxEndOfStack, pxTaskCode, pvParameters ); + } + #endif /* portSTACK_GROWTH */ + } + #else /* portHAS_STACK_OVERFLOW_CHECKING */ + { + pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pxTaskCode, pvParameters ); + } + #endif /* portHAS_STACK_OVERFLOW_CHECKING */ + } + #endif /* portUSING_MPU_WRAPPERS */ + + if( pxCreatedTask != NULL ) + { + /* Pass the handle out in an anonymous way. The handle can be used to + change the created task's priority, delete the created task, etc.*/ + *pxCreatedTask = ( TaskHandle_t ) pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) +{ + /* Ensure interrupts don't access the task lists while the lists are being + updated. */ + taskENTER_CRITICAL(); + { + uxCurrentNumberOfTasks++; + if( pxCurrentTCB == NULL ) + { + /* There are no other tasks, or all the other tasks are in + the suspended state - make this the current task. */ + pxCurrentTCB = pxNewTCB; + + if( uxCurrentNumberOfTasks == ( UBaseType_t ) 1 ) + { + /* This is the first task to be created so do the preliminary + initialisation required. We will not recover if this call + fails, but we will report the failure. */ + prvInitialiseTaskLists(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* If the scheduler is not already running, make this task the + current task if it is the highest priority task to be created + so far. */ + if( xSchedulerRunning == pdFALSE ) + { + if( pxCurrentTCB->uxPriority <= pxNewTCB->uxPriority ) + { + pxCurrentTCB = pxNewTCB; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + uxTaskNumber++; + + #if ( configUSE_TRACE_FACILITY == 1 ) + { + /* Add a counter into the TCB for tracing only. */ + pxNewTCB->uxTCBNumber = uxTaskNumber; + } + #endif /* configUSE_TRACE_FACILITY */ + traceTASK_CREATE( pxNewTCB ); + + prvAddTaskToReadyList( pxNewTCB ); + + portSETUP_TCB( pxNewTCB ); + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* If the created task is of a higher priority than the current task + then it should run now. */ + if( pxCurrentTCB->uxPriority < pxNewTCB->uxPriority ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + void vTaskDelete( TaskHandle_t xTaskToDelete ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the calling task that is + being deleted. */ + pxTCB = prvGetTCBFromHandle( xTaskToDelete ); + + /* Remove task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Increment the uxTaskNumber also so kernel aware debuggers can + detect that the task lists need re-generating. This is done before + portPRE_TASK_DELETE_HOOK() as in the Windows port that macro will + not return. */ + uxTaskNumber++; + + if( pxTCB == pxCurrentTCB ) + { + /* A task is deleting itself. This cannot complete within the + task itself, as a context switch to another task is required. + Place the task in the termination list. The idle task will + check the termination list and free up any memory allocated by + the scheduler for the TCB and stack of the deleted task. */ + vListInsertEnd( &xTasksWaitingTermination, &( pxTCB->xStateListItem ) ); + + /* Increment the ucTasksDeleted variable so the idle task knows + there is a task that has been deleted and that it should therefore + check the xTasksWaitingTermination list. */ + ++uxDeletedTasksWaitingCleanUp; + + /* The pre-delete hook is primarily for the Windows simulator, + in which Windows specific clean up operations are performed, + after which it is not possible to yield away from this task - + hence xYieldPending is used to latch that a context switch is + required. */ + portPRE_TASK_DELETE_HOOK( pxTCB, &xYieldPending ); + } + else + { + --uxCurrentNumberOfTasks; + prvDeleteTCB( pxTCB ); + + /* Reset the next expected unblock time in case it referred to + the task that has just been deleted. */ + prvResetNextTaskUnblockTime(); + } + + traceTASK_DELETE( pxTCB ); + } + taskEXIT_CRITICAL(); + + /* Force a reschedule if it is the currently running task that has just + been deleted. */ + if( xSchedulerRunning != pdFALSE ) + { + if( pxTCB == pxCurrentTCB ) + { + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelayUntil == 1 ) + + void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement ) + { + TickType_t xTimeToWake; + BaseType_t xAlreadyYielded, xShouldDelay = pdFALSE; + + configASSERT( pxPreviousWakeTime ); + configASSERT( ( xTimeIncrement > 0U ) ); + configASSERT( uxSchedulerSuspended == 0 ); + + vTaskSuspendAll(); + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount; + + /* Generate the tick time at which the task wants to wake. */ + xTimeToWake = *pxPreviousWakeTime + xTimeIncrement; + + if( xConstTickCount < *pxPreviousWakeTime ) + { + /* The tick count has overflowed since this function was + lasted called. In this case the only time we should ever + actually delay is if the wake time has also overflowed, + and the wake time is greater than the tick time. When this + is the case it is as if neither time had overflowed. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) && ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The tick time has not overflowed. In this case we will + delay if either the wake time has overflowed, and/or the + tick time is less than the wake time. */ + if( ( xTimeToWake < *pxPreviousWakeTime ) || ( xTimeToWake > xConstTickCount ) ) + { + xShouldDelay = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Update the wake time ready for the next call. */ + *pxPreviousWakeTime = xTimeToWake; + + if( xShouldDelay != pdFALSE ) + { + traceTASK_DELAY_UNTIL( xTimeToWake ); + + /* prvAddCurrentTaskToDelayedList() needs the block time, not + the time to wake, so subtract the current tick count. */ + prvAddCurrentTaskToDelayedList( xTimeToWake - xConstTickCount, pdFALSE ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + xAlreadyYielded = xTaskResumeAll(); + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelayUntil */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelay == 1 ) + + void vTaskDelay( const TickType_t xTicksToDelay ) + { + BaseType_t xAlreadyYielded = pdFALSE; + + /* A delay time of zero just forces a reschedule. */ + if( xTicksToDelay > ( TickType_t ) 0U ) + { + configASSERT( uxSchedulerSuspended == 0 ); + vTaskSuspendAll(); + { + traceTASK_DELAY(); + + /* A task that is removed from the event list while the + scheduler is suspended will not get placed in the ready + list or removed from the blocked list until the scheduler + is resumed. + + This task cannot be in an event list as it is the currently + executing task. */ + prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE ); + } + xAlreadyYielded = xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Force a reschedule if xTaskResumeAll has not already done so, we may + have put ourselves to sleep. */ + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskDelay */ +/*-----------------------------------------------------------*/ + +#if( ( INCLUDE_eTaskGetState == 1 ) || ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_xTaskAbortDelay == 1 ) ) + + eTaskState eTaskGetState( TaskHandle_t xTask ) + { + eTaskState eReturn; + List_t const * pxStateList, *pxDelayedList, *pxOverflowedDelayedList; + const TCB_t * const pxTCB = xTask; + + configASSERT( pxTCB ); + + if( pxTCB == pxCurrentTCB ) + { + /* The task calling this function is querying its own state. */ + eReturn = eRunning; + } + else + { + taskENTER_CRITICAL(); + { + pxStateList = listLIST_ITEM_CONTAINER( &( pxTCB->xStateListItem ) ); + pxDelayedList = pxDelayedTaskList; + pxOverflowedDelayedList = pxOverflowDelayedTaskList; + } + taskEXIT_CRITICAL(); + + if( ( pxStateList == pxDelayedList ) || ( pxStateList == pxOverflowedDelayedList ) ) + { + /* The task being queried is referenced from one of the Blocked + lists. */ + eReturn = eBlocked; + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + else if( pxStateList == &xSuspendedTaskList ) + { + /* The task being queried is referenced from the suspended + list. Is it genuinely suspended or is it blocked + indefinitely? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ) + { + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + /* The task does not appear on the event list item of + and of the RTOS objects, but could still be in the + blocked state if it is waiting on its notification + rather than waiting on an object. */ + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + eReturn = eBlocked; + } + else + { + eReturn = eSuspended; + } + } + #else + { + eReturn = eSuspended; + } + #endif + } + else + { + eReturn = eBlocked; + } + } + #endif + + #if ( INCLUDE_vTaskDelete == 1 ) + else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) + { + /* The task being queried is referenced from the deleted + tasks list, or it is not referenced from any lists at + all. */ + eReturn = eDeleted; + } + #endif + + else /*lint !e525 Negative indentation is intended to make use of pre-processor clearer. */ + { + /* If the task is not in any other state, it must be in the + Ready (including pending ready) state. */ + eReturn = eReady; + } + } + + return eReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_eTaskGetState */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGet( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the task + that called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + taskEXIT_CRITICAL(); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskPriorityGet == 1 ) + + UBaseType_t uxTaskPriorityGetFromISR( const TaskHandle_t xTask ) + { + TCB_t const *pxTCB; + UBaseType_t uxReturn, uxSavedInterruptState; + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptState = portSET_INTERRUPT_MASK_FROM_ISR(); + { + /* If null is passed in here then it is the priority of the calling + task that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); + uxReturn = pxTCB->uxPriority; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptState ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskPriorityGet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskPrioritySet == 1 ) + + void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) + { + TCB_t *pxTCB; + UBaseType_t uxCurrentBasePriority, uxPriorityUsedOnEntry; + BaseType_t xYieldRequired = pdFALSE; + + configASSERT( ( uxNewPriority < configMAX_PRIORITIES ) ); + + /* Ensure the new priority is valid. */ + if( uxNewPriority >= ( UBaseType_t ) configMAX_PRIORITIES ) + { + uxNewPriority = ( UBaseType_t ) configMAX_PRIORITIES - ( UBaseType_t ) 1U; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the calling + task that is being changed. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + traceTASK_PRIORITY_SET( pxTCB, uxNewPriority ); + + #if ( configUSE_MUTEXES == 1 ) + { + uxCurrentBasePriority = pxTCB->uxBasePriority; + } + #else + { + uxCurrentBasePriority = pxTCB->uxPriority; + } + #endif + + if( uxCurrentBasePriority != uxNewPriority ) + { + /* The priority change may have readied a task of higher + priority than the calling task. */ + if( uxNewPriority > uxCurrentBasePriority ) + { + if( pxTCB != pxCurrentTCB ) + { + /* The priority of a task other than the currently + running task is being raised. Is the priority being + raised above that of the running task? */ + if( uxNewPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + /* The priority of the running task is being raised, + but the running task must already be the highest + priority task able to run so no yield is required. */ + } + } + else if( pxTCB == pxCurrentTCB ) + { + /* Setting the priority of the running task down means + there may now be another task of higher priority that + is ready to execute. */ + xYieldRequired = pdTRUE; + } + else + { + /* Setting the priority of any other task down does not + require a yield as the running task must be above the + new priority of the task being modified. */ + } + + /* Remember the ready list the task might be referenced from + before its uxPriority member is changed so the + taskRESET_READY_PRIORITY() macro can function correctly. */ + uxPriorityUsedOnEntry = pxTCB->uxPriority; + + #if ( configUSE_MUTEXES == 1 ) + { + /* Only change the priority being used if the task is not + currently using an inherited priority. */ + if( pxTCB->uxBasePriority == pxTCB->uxPriority ) + { + pxTCB->uxPriority = uxNewPriority; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* The base priority gets set whatever. */ + pxTCB->uxBasePriority = uxNewPriority; + } + #else + { + pxTCB->uxPriority = uxNewPriority; + } + #endif + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxNewPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task is in the blocked or suspended list we need do + nothing more than change its priority variable. However, if + the task is in a ready list it needs to be removed and placed + in the list appropriate to its new priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* The task is currently in its ready list - remove before + adding it to it's new ready list. As we are in a critical + section we can do this even if the scheduler is suspended. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* It is known that the task is in its ready list so + there is no need to check again and the port level + reset macro can be called directly. */ + portRESET_READY_PRIORITY( uxPriorityUsedOnEntry, uxTopReadyPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xYieldRequired != pdFALSE ) + { + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Remove compiler warning about unused variables when the port + optimised task selection is not being used. */ + ( void ) uxPriorityUsedOnEntry; + } + } + taskEXIT_CRITICAL(); + } + +#endif /* INCLUDE_vTaskPrioritySet */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskSuspend( TaskHandle_t xTaskToSuspend ) + { + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the running task that is + being suspended. */ + pxTCB = prvGetTCBFromHandle( xTaskToSuspend ); + + traceTASK_SUSPEND( pxTCB ); + + /* Remove task from the ready/delayed list and place in the + suspended list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Is the task waiting on an event also? */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + traceMOVED_TASK_TO_SUSPENDED_LIST(pxTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ); + + #if( configUSE_TASK_NOTIFICATIONS == 1 ) + { + if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task was blocked to wait for a notification, but is + now suspended, so no notification was received. */ + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + } + #endif + } + taskEXIT_CRITICAL(); + + if( xSchedulerRunning != pdFALSE ) + { + /* Reset the next expected unblock time in case it referred to the + task that is now in the Suspended state. */ + taskENTER_CRITICAL(); + { + prvResetNextTaskUnblockTime(); + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( pxTCB == pxCurrentTCB ) + { + if( xSchedulerRunning != pdFALSE ) + { + /* The current task has just been suspended. */ + configASSERT( uxSchedulerSuspended == 0 ); + portYIELD_WITHIN_API(); + } + else + { + /* The scheduler is not running, but the task that was pointed + to by pxCurrentTCB has just been suspended and pxCurrentTCB + must be adjusted to point to a different task. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == uxCurrentNumberOfTasks ) /*lint !e931 Right has no side effect, just volatile. */ + { + /* No other tasks are ready, so set pxCurrentTCB back to + NULL so when the next task is created pxCurrentTCB will + be set to point to it no matter what its relative priority + is. */ + pxCurrentTCB = NULL; + } + else + { + vTaskSwitchContext(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + static BaseType_t prvTaskIsTaskSuspended( const TaskHandle_t xTask ) + { + BaseType_t xReturn = pdFALSE; + const TCB_t * const pxTCB = xTask; + + /* Accesses xPendingReadyList so must be called from a critical + section. */ + + /* It does not make sense to check if the calling task is suspended. */ + configASSERT( xTask ); + + /* Is the task being resumed actually in the suspended list? */ + if( listIS_CONTAINED_WITHIN( &xSuspendedTaskList, &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + /* Has the task already been resumed from within an ISR? */ + if( listIS_CONTAINED_WITHIN( &xPendingReadyList, &( pxTCB->xEventListItem ) ) == pdFALSE ) + { + /* Is it in the suspended list because it is in the Suspended + state, or because is is blocked with no timeout? */ + if( listIS_CONTAINED_WITHIN( NULL, &( pxTCB->xEventListItem ) ) != pdFALSE ) /*lint !e961. The cast is only redundant when NULL is used. */ + { + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } /*lint !e818 xTask cannot be a pointer to const because it is a typedef. */ + +#endif /* INCLUDE_vTaskSuspend */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskSuspend == 1 ) + + void vTaskResume( TaskHandle_t xTaskToResume ) + { + TCB_t * const pxTCB = xTaskToResume; + + /* It does not make sense to resume the calling task. */ + configASSERT( xTaskToResume ); + + /* The parameter cannot be NULL as it is impossible to resume the + currently executing task. */ + if( ( pxTCB != pxCurrentTCB ) && ( pxTCB != NULL ) ) + { + taskENTER_CRITICAL(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME( pxTCB ); + + /* The ready list can be accessed even if the scheduler is + suspended because this is inside a critical section. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* A higher priority task may have just been resumed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + /* This yield may not cause the task just resumed to run, + but will leave the lists in the correct state for the + next yield. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* INCLUDE_vTaskSuspend */ + +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) + + BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) + { + BaseType_t xYieldRequired = pdFALSE; + TCB_t * const pxTCB = xTaskToResume; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToResume ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( prvTaskIsTaskSuspended( pxTCB ) != pdFALSE ) + { + traceTASK_RESUME_FROM_ISR( pxTCB ); + + /* Check the ready lists can be accessed. */ + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Ready lists can be accessed so move the task from the + suspended list to the ready list directly. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed or ready lists cannot be accessed so the task + is held in the pending ready list until the scheduler is + unsuspended. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xYieldRequired; + } + +#endif /* ( ( INCLUDE_xTaskResumeFromISR == 1 ) && ( INCLUDE_vTaskSuspend == 1 ) ) */ +/*-----------------------------------------------------------*/ + +void vTaskStartScheduler( void ) +{ +BaseType_t xReturn; + + /* Add the idle task at the lowest priority. */ + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxIdleTaskTCBBuffer = NULL; + StackType_t *pxIdleTaskStackBuffer = NULL; + uint32_t ulIdleTaskStackSize; + + /* The Idle task is created using user provided RAM - obtain the + address of the RAM then create the idle task. */ + vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &ulIdleTaskStackSize ); + xIdleTaskHandle = xTaskCreateStatic( prvIdleTask, + configIDLE_TASK_NAME, + ulIdleTaskStackSize, + ( void * ) NULL, /*lint !e961. The cast is not redundant for all compilers. */ + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + pxIdleTaskStackBuffer, + pxIdleTaskTCBBuffer ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + + if( xIdleTaskHandle != NULL ) + { + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + #else + { + /* The Idle task is being created using dynamically allocated RAM. */ + xReturn = xTaskCreate( prvIdleTask, + configIDLE_TASK_NAME, + configMINIMAL_STACK_SIZE, + ( void * ) NULL, + portPRIVILEGE_BIT, /* In effect ( tskIDLE_PRIORITY | portPRIVILEGE_BIT ), but tskIDLE_PRIORITY is zero. */ + &xIdleTaskHandle ); /*lint !e961 MISRA exception, justified as it is not a redundant explicit cast to all supported compilers. */ + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + + #if ( configUSE_TIMERS == 1 ) + { + if( xReturn == pdPASS ) + { + xReturn = xTimerCreateTimerTask(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TIMERS */ + + if( xReturn == pdPASS ) + { + /* freertos_tasks_c_additions_init() should only be called if the user + definable macro FREERTOS_TASKS_C_ADDITIONS_INIT() is defined, as that is + the only macro called by the function. */ + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + { + freertos_tasks_c_additions_init(); + } + #endif + + /* Interrupts are turned off here, to ensure a tick does not occur + before or during the call to xPortStartScheduler(). The stacks of + the created tasks contain a status word with interrupts switched on + so interrupts will automatically get re-enabled when the first task + starts to run. */ + portDISABLE_INTERRUPTS(); + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to the task that will run first. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + xNextTaskUnblockTime = portMAX_DELAY; + xSchedulerRunning = pdTRUE; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + + /* If configGENERATE_RUN_TIME_STATS is defined then the following + macro must be defined to configure the timer/counter used to generate + the run time counter time base. NOTE: If configGENERATE_RUN_TIME_STATS + is set to 0 and the following line fails to build then ensure you do not + have portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() defined in your + FreeRTOSConfig.h file. */ + portCONFIGURE_TIMER_FOR_RUN_TIME_STATS(); + + traceTASK_SWITCHED_IN(); + + /* Setting up the timer tick is hardware specific and thus in the + portable interface. */ + if( xPortStartScheduler() != pdFALSE ) + { + /* Should not reach here as if the scheduler is running the + function will not return. */ + } + else + { + /* Should only reach here if a task calls xTaskEndScheduler(). */ + } + } + else + { + /* This line will only be reached if the kernel could not be started, + because there was not enough FreeRTOS heap to create the idle task + or the timer task. */ + configASSERT( xReturn != errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY ); + } + + /* Prevent compiler warnings if INCLUDE_xTaskGetIdleTaskHandle is set to 0, + meaning xIdleTaskHandle is not used anywhere else. */ + ( void ) xIdleTaskHandle; +} +/*-----------------------------------------------------------*/ + +#if INCLUDE_vTaskEndScheduler /* << EST */ +#include "queue.h" +void vTaskEndScheduler( void ) +{ + /* Stop the scheduler interrupts and call the portable scheduler end + routine so the original ISRs can be restored if necessary. The port + layer must ensure interrupts enable bit is left in the correct state. */ + portDISABLE_INTERRUPTS(); + xSchedulerRunning = pdFALSE; + /* << EST initialize back things for properly ending the scheduler */ + /* set back the scheduler and tasks */ + pxCurrentTCB = NULL; + memset(pxReadyTasksLists, 0, sizeof(pxReadyTasksLists)); + memset(&xDelayedTaskList1, 0, sizeof(xDelayedTaskList1)); + pxDelayedTaskList = NULL; + pxOverflowDelayedTaskList = NULL; + memset(&xPendingReadyList, 0, sizeof(xPendingReadyList)); + + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT; + uxTopReadyPriority = tskIDLE_PRIORITY; + uxPendedTicks = ( UBaseType_t ) 0U; + xYieldPending = pdFALSE; + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; /* Initialised to portMAX_DELAY before the scheduler starts. */ + xIdleTaskHandle = NULL; /*< Holds the handle of the idle task. The idle task is created automatically when the scheduler is started. */ + + /* reset the queues */ + vQueueEndScheduler(); + /* now do the very low level stuff and reset the heap memory if possible */ + /* << EST end */ + vPortEndScheduler(); +} +#endif /* << EST */ +/*----------------------------------------------------------*/ + +void vTaskSuspendAll( void ) +{ + /* A critical section is not required as the variable is of type + BaseType_t. Please read Richard Barry's reply in the following link to a + post in the FreeRTOS support forum before reporting this as a bug! - + http://goo.gl/wu4acr */ + ++uxSchedulerSuspended; + portMEMORY_BARRIER(); +} +/*----------------------------------------------------------*/ + +#if ( configUSE_TICKLESS_IDLE != 0 ) + + static TickType_t prvGetExpectedIdleTime( void ) + { + TickType_t xReturn; + UBaseType_t uxHigherPriorityReadyTasks = pdFALSE; + + /* uxHigherPriorityReadyTasks takes care of the case where + configUSE_PREEMPTION is 0, so there may be tasks above the idle priority + task that are in the Ready state, even though the idle task is + running. */ + #if( configUSE_PORT_OPTIMISED_TASK_SELECTION == 0 ) + { + if( uxTopReadyPriority > tskIDLE_PRIORITY ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #else + { + const UBaseType_t uxLeastSignificantBit = ( UBaseType_t ) 0x01; + + /* When port optimised task selection is used the uxTopReadyPriority + variable is used as a bit map. If bits other than the least + significant bit are set then there are tasks that have a priority + above the idle priority that are in the Ready state. This takes + care of the case where the co-operative scheduler is in use. */ + if( uxTopReadyPriority > uxLeastSignificantBit ) + { + uxHigherPriorityReadyTasks = pdTRUE; + } + } + #endif + + if( pxCurrentTCB->uxPriority > tskIDLE_PRIORITY ) + { + xReturn = 0; + } + else if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > 1 ) + { + /* There are other idle priority tasks in the ready state. If + time slicing is used then the very next tick interrupt must be + processed. */ + xReturn = 0; + } + else if( uxHigherPriorityReadyTasks != pdFALSE ) + { + /* There are tasks in the Ready state that have a priority above the + idle priority. This path can only be reached if + configUSE_PREEMPTION is 0. */ + xReturn = 0; + } + else + { + xReturn = xNextTaskUnblockTime - xTickCount; + } + + return xReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskResumeAll( void ) +{ +TCB_t *pxTCB = NULL; +BaseType_t xAlreadyYielded = pdFALSE; + + /* If uxSchedulerSuspended is zero then this function does not match a + previous call to vTaskSuspendAll(). */ + configASSERT( uxSchedulerSuspended ); + + /* It is possible that an ISR caused a task to be removed from an event + list while the scheduler was suspended. If this was the case then the + removed task will have been added to the xPendingReadyList. Once the + scheduler has been resumed it is safe to move all the pending ready + tasks from this list into their appropriate ready list. */ + taskENTER_CRITICAL(); + { + --uxSchedulerSuspended; + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + if( uxCurrentNumberOfTasks > ( UBaseType_t ) 0U ) + { + /* Move any readied tasks from the pending list into the + appropriate ready list. */ + while( listLIST_IS_EMPTY( &xPendingReadyList ) == pdFALSE ) + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xPendingReadyList ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* If the moved task has a priority higher than the current + task then a yield must be performed. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( pxTCB != NULL ) + { + /* A task was unblocked while the scheduler was suspended, + which may have prevented the next unblock time from being + re-calculated, in which case re-calculate it now. Mainly + important for low power tickless implementations, where + this can prevent an unnecessary exit from low power + state. */ + prvResetNextTaskUnblockTime(); + } + + /* If any ticks occurred while the scheduler was suspended then + they should be processed now. This ensures the tick count does + not slip, and that any delayed tasks are resumed at the correct + time. */ + { + UBaseType_t uxPendedCounts = uxPendedTicks; /* Non-volatile copy. */ + + if( uxPendedCounts > ( UBaseType_t ) 0U ) + { + do + { + if( xTaskIncrementTick() != pdFALSE ) + { + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + --uxPendedCounts; + } while( uxPendedCounts > ( UBaseType_t ) 0U ); + + uxPendedTicks = 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + if( xYieldPending != pdFALSE ) + { + #if( configUSE_PREEMPTION != 0 ) + { + xAlreadyYielded = pdTRUE; + } + #endif + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xAlreadyYielded; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCount( void ) +{ +TickType_t xTicks; + + /* Critical section required if running on a 16 bit processor. */ + portTICK_TYPE_ENTER_CRITICAL(); + { + xTicks = xTickCount; + } + portTICK_TYPE_EXIT_CRITICAL(); + + return xTicks; +} +/*-----------------------------------------------------------*/ + +TickType_t xTaskGetTickCountFromISR( void ) +{ +TickType_t xReturn; +UBaseType_t uxSavedInterruptStatus; + + /* RTOS ports that support interrupt nesting have the concept of a maximum + system call (or maximum API call) interrupt priority. Interrupts that are + above the maximum system call priority are kept permanently enabled, even + when the RTOS kernel is in a critical section, but cannot make any calls to + FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h + then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has been + assigned a priority above the configured maximum system call priority. + Only FreeRTOS functions that end in FromISR can be called from interrupts + that have been assigned a priority at or (logically) below the maximum + system call interrupt priority. FreeRTOS maintains a separate interrupt + safe API to ensure interrupt entry is as fast and as simple as possible. + More information (albeit Cortex-M specific) is provided on the following + link: https://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + uxSavedInterruptStatus = portTICK_TYPE_SET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = xTickCount; + } + portTICK_TYPE_CLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +UBaseType_t uxTaskGetNumberOfTasks( void ) +{ + /* A critical section is not required because the variables are of type + BaseType_t. */ + return uxCurrentNumberOfTasks; +} +/*-----------------------------------------------------------*/ + +char *pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +TCB_t *pxTCB; + + /* If null is passed in here then the name of the calling task is being + queried. */ + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + configASSERT( pxTCB ); + return &( pxTCB->pcTaskName[ 0 ] ); +} +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + static TCB_t *prvSearchForNameWithinSingleList( List_t *pxList, const char pcNameToQuery[] ) + { + TCB_t *pxNextTCB, *pxFirstTCB, *pxReturn = NULL; + UBaseType_t x; + char cNextChar; + BaseType_t xBreakLoop; + + /* This function is called with the scheduler suspended. */ + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Check each character in the name looking for a match or + mismatch. */ + xBreakLoop = pdFALSE; + for( x = ( UBaseType_t ) 0; x < ( UBaseType_t ) configMAX_TASK_NAME_LEN; x++ ) + { + cNextChar = pxNextTCB->pcTaskName[ x ]; + + if( cNextChar != pcNameToQuery[ x ] ) + { + /* Characters didn't match. */ + xBreakLoop = pdTRUE; + } + else if( cNextChar == ( char ) 0x00 ) + { + /* Both strings terminated, a match must have been + found. */ + pxReturn = pxNextTCB; + xBreakLoop = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + if( xBreakLoop != pdFALSE ) + { + break; + } + } + + if( pxReturn != NULL ) + { + /* The handle has been found. */ + break; + } + + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return pxReturn; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetHandle == 1 ) + + TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + { + UBaseType_t uxQueue = configMAX_PRIORITIES; + TCB_t* pxTCB; + + /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ + configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); + + vTaskSuspendAll(); + { + /* Search the ready lists. */ + do + { + uxQueue--; + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) &( pxReadyTasksLists[ uxQueue ] ), pcNameToQuery ); + + if( pxTCB != NULL ) + { + /* Found the handle. */ + break; + } + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxDelayedTaskList, pcNameToQuery ); + } + + if( pxTCB == NULL ) + { + pxTCB = prvSearchForNameWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pcNameToQuery ); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the suspended list. */ + pxTCB = prvSearchForNameWithinSingleList( &xSuspendedTaskList, pcNameToQuery ); + } + } + #endif + + #if( INCLUDE_vTaskDelete == 1 ) + { + if( pxTCB == NULL ) + { + /* Search the deleted list. */ + pxTCB = prvSearchForNameWithinSingleList( &xTasksWaitingTermination, pcNameToQuery ); + } + } + #endif + } + ( void ) xTaskResumeAll(); + + return pxTCB; + } + +#endif /* INCLUDE_xTaskGetHandle */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetSystemState( TaskStatus_t * const pxTaskStatusArray, const UBaseType_t uxArraySize, uint32_t * const pulTotalRunTime ) + { + UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; + + vTaskSuspendAll(); + { + /* Is there a space in the array for each task in the system? */ + if( uxArraySize >= uxCurrentNumberOfTasks ) + { + /* Fill in an TaskStatus_t structure with information on each + task in the Ready state. */ + do + { + uxQueue--; + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &( pxReadyTasksLists[ uxQueue ] ), eReady ); + + } while( uxQueue > ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Fill in an TaskStatus_t structure with information on each + task in the Blocked state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxDelayedTaskList, eBlocked ); + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), ( List_t * ) pxOverflowDelayedTaskList, eBlocked ); + + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task that has been deleted but not yet cleaned up. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xTasksWaitingTermination, eDeleted ); + } + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Fill in an TaskStatus_t structure with information on + each task in the Suspended state. */ + uxTask += prvListTasksWithinSingleList( &( pxTaskStatusArray[ uxTask ] ), &xSuspendedTaskList, eSuspended ); + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1) + { + if( pulTotalRunTime != NULL ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ( *pulTotalRunTime ) ); + #else + *pulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + } + } + #else + { + if( pulTotalRunTime != NULL ) + { + *pulTotalRunTime = 0; + } + } + #endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) + + TaskHandle_t xTaskGetIdleTaskHandle( void ) + { + /* If xTaskGetIdleTaskHandle() is called before the scheduler has been + started, then xIdleTaskHandle will be NULL. */ + configASSERT( ( xIdleTaskHandle != NULL ) ); + return xIdleTaskHandle; + } + +#endif /* INCLUDE_xTaskGetIdleTaskHandle */ +/*----------------------------------------------------------*/ + +/* This conditional compilation should use inequality to 0, not equality to 1. +This is to ensure vTaskStepTick() is available when user defined low power mode +implementations require configUSE_TICKLESS_IDLE to be set to a value other than +1. */ +#if ( configUSE_TICKLESS_IDLE != 0 ) + + void vTaskStepTick( const TickType_t xTicksToJump ) + { + /* Correct the tick count value after a period during which the tick + was suppressed. Note this does *not* call the tick hook function for + each stepped tick. */ + configASSERT( ( xTickCount + xTicksToJump ) <= xNextTaskUnblockTime ); + xTickCount += xTicksToJump; + traceINCREASE_TICK_COUNT( xTicksToJump ); + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*----------------------------------------------------------*/ + +#if ( INCLUDE_xTaskAbortDelay == 1 ) + + BaseType_t xTaskAbortDelay( TaskHandle_t xTask ) + { + TCB_t *pxTCB = xTask; + BaseType_t xReturn; + + configASSERT( pxTCB ); + + vTaskSuspendAll(); + { + /* A task can only be prematurely removed from the Blocked state if + it is actually in the Blocked state. */ + if( eTaskGetState( xTask ) == eBlocked ) + { + xReturn = pdPASS; + + /* Remove the reference to the task from the blocked list. An + interrupt won't touch the xStateListItem because the + scheduler is suspended. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove it from + the event list too. Interrupts can touch the event list item, + even though the scheduler is suspended, so a critical section + is used. */ + taskENTER_CRITICAL(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + pxTCB->ucDelayAborted = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + /* Place the unblocked task into the appropriate ready list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate context + switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should only be + performed if the unblocked task has a priority that is + equal to or higher than the currently executing task. */ + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Pend the yield to be performed when the scheduler + is unsuspended. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + else + { + xReturn = pdFAIL; + } + } + ( void ) xTaskResumeAll(); + + return xReturn; + } + +#endif /* INCLUDE_xTaskAbortDelay */ +/*----------------------------------------------------------*/ + +BaseType_t xTaskIncrementTick( void ) +{ +TCB_t * pxTCB; +TickType_t xItemValue; +BaseType_t xSwitchRequired = pdFALSE; + + /* Called by the portable layer each time a tick interrupt occurs. + Increments the tick then checks to see if the new tick value will cause any + tasks to be unblocked. */ + traceTASK_INCREMENT_TICK( xTickCount ); + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + /* Minor optimisation. The tick count cannot change in this + block. */ + const TickType_t xConstTickCount = xTickCount + ( TickType_t ) 1; + + /* Increment the RTOS tick, switching the delayed and overflowed + delayed lists if it wraps to 0. */ + xTickCount = xConstTickCount; + + if( xConstTickCount == ( TickType_t ) 0U ) /*lint !e774 'if' does not always evaluate to false as it is looking for an overflow. */ + { + taskSWITCH_DELAYED_LISTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* See if this tick has made a timeout expire. Tasks are stored in + the queue in the order of their wake time - meaning once one task + has been found whose block time has not expired there is no need to + look any further down the list. */ + if( xConstTickCount >= xNextTaskUnblockTime ) + { + for( ;; ) + { + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The delayed list is empty. Set xNextTaskUnblockTime + to the maximum possible value so it is extremely + unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass + next time through. */ + xNextTaskUnblockTime = portMAX_DELAY; /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + break; + } + else + { + /* The delayed list is not empty, get the value of the + item at the head of the delayed list. This is the time + at which the task at the head of the delayed list must + be removed from the Blocked state. */ + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xItemValue = listGET_LIST_ITEM_VALUE( &( pxTCB->xStateListItem ) ); + + if( xConstTickCount < xItemValue ) + { + /* It is not time to unblock this item yet, but the + item value is the time at which the task at the head + of the blocked list must be removed from the Blocked + state - so record the item value in + xNextTaskUnblockTime. */ + xNextTaskUnblockTime = xItemValue; + break; /*lint !e9011 Code structure here is deedmed easier to understand with multiple breaks. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* It is time to remove the item from the Blocked state. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + + /* Is the task waiting on an event also? If so remove + it from the event list. */ + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + ( void ) uxListRemove( &( pxTCB->xEventListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Place the unblocked task into the appropriate ready + list. */ + prvAddTaskToReadyList( pxTCB ); + + /* A task being unblocked cannot cause an immediate + context switch if preemption is turned off. */ + #if ( configUSE_PREEMPTION == 1 ) + { + /* Preemption is on, but a context switch should + only be performed if the unblocked task has a + priority that is equal to or higher than the + currently executing task. */ + if( pxTCB->uxPriority >= pxCurrentTCB->uxPriority ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + } + } + } + + /* Tasks of equal priority to the currently running task will share + processing time (time slice) if preemption is on, and the application + writer has not explicitly turned time slicing off. */ + #if ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) + { + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ pxCurrentTCB->uxPriority ] ) ) > ( UBaseType_t ) 1 ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configUSE_TIME_SLICING == 1 ) ) */ + + #if ( configUSE_TICK_HOOK == 1 ) + { + /* Guard against the tick hook being called when the pended tick + count is being unwound (when the scheduler is being unlocked). */ + if( uxPendedTicks == ( UBaseType_t ) 0U ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICK_HOOK */ + } + else + { + ++uxPendedTicks; + + /* The tick hook gets called at regular intervals, even if the + scheduler is locked. */ + #if ( configUSE_TICK_HOOK == 1 ) + { +#if 1 + /* << EST: using configuration name macro */ + extern void configUSE_TICK_HOOK_NAME(void); + configUSE_TICK_HOOK_NAME(); +#else + vApplicationTickHook(); +#endif + } + #endif + } + + #if ( configUSE_PREEMPTION == 1 ) + { + if( xYieldPending != pdFALSE ) + { + xSwitchRequired = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_PREEMPTION */ + + return xSwitchRequired; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + void vTaskSetApplicationTaskTag( TaskHandle_t xTask, TaskHookFunction_t pxHookFunction ) + { + TCB_t *xTCB; + + /* If xTask is NULL then it is the task hook of the calling task that is + getting set. */ + if( xTask == NULL ) + { + xTCB = ( TCB_t * ) pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xTCB->pxTaskTag = pxHookFunction; + } + taskEXIT_CRITICAL(); + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTag( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + taskENTER_CRITICAL(); + { + xReturn = pxTCB->pxTaskTag; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + TaskHookFunction_t xTaskGetApplicationTaskTagFromISR( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + TaskHookFunction_t xReturn; + UBaseType_t uxSavedInterruptStatus; + + /* If xTask is NULL then set the calling task's hook. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + /* Save the hook function in the TCB. A critical section is required as + the value can be accessed from an interrupt. */ + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + xReturn = pxTCB->pxTaskTag; + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_APPLICATION_TASK_TAG == 1 ) + + BaseType_t xTaskCallApplicationTaskHook( TaskHandle_t xTask, void *pvParameter ) + { + TCB_t *xTCB; + BaseType_t xReturn; + + /* If xTask is NULL then we are calling our own task hook. */ + if( xTask == NULL ) + { + xTCB = pxCurrentTCB; + } + else + { + xTCB = xTask; + } + + if( xTCB->pxTaskTag != NULL ) + { + xReturn = xTCB->pxTaskTag( pvParameter ); + } + else + { + xReturn = pdFAIL; + } + + return xReturn; + } + +#endif /* configUSE_APPLICATION_TASK_TAG */ +/*-----------------------------------------------------------*/ + +#ifdef __GNUC__ /* << EST */ +__attribute__((used)) /* using C++ compiler, vTaskSwitchContext() might be removed even with -O0? */ +#endif +void vTaskSwitchContext( void ) +{ + if( uxSchedulerSuspended != ( UBaseType_t ) pdFALSE ) + { + /* The scheduler is currently suspended - do not allow a context + switch. */ + xYieldPending = pdTRUE; + } + else + { + xYieldPending = pdFALSE; + traceTASK_SWITCHED_OUT(); + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + #ifdef portALT_GET_RUN_TIME_COUNTER_VALUE + portALT_GET_RUN_TIME_COUNTER_VALUE( ulTotalRunTime ); + #else + ulTotalRunTime = portGET_RUN_TIME_COUNTER_VALUE(); + #endif + + /* Add the amount of time the task has been running to the + accumulated time so far. The time the task started running was + stored in ulTaskSwitchedInTime. Note that there is no overflow + protection here so count values are only valid until the timer + overflows. The guard against negative values is to protect + against suspect run time stat counter implementations - which + are provided by the application, not the kernel. */ + if( ulTotalRunTime > ulTaskSwitchedInTime ) + { + pxCurrentTCB->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + ulTaskSwitchedInTime = ulTotalRunTime; + } + #endif /* configGENERATE_RUN_TIME_STATS */ + + /* Check for stack overflow, if configured. */ + taskCHECK_FOR_STACK_OVERFLOW(); + + /* Before the currently running task is switched out, save its errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + pxCurrentTCB->iTaskErrno = FreeRTOS_errno; + } + #endif + + /* Select a new task to run using either the generic C or port + optimised asm code. */ + taskSELECT_HIGHEST_PRIORITY_TASK(); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + traceTASK_SWITCHED_IN(); + + /* After the new task is switched in, update the global errno. */ + #if( configUSE_POSIX_ERRNO == 1 ) + { + FreeRTOS_errno = pxCurrentTCB->iTaskErrno; + } + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + /* Switch Newlib's _impure_ptr variable to point to the _reent + structure specific to this task. */ + _impure_ptr = &( pxCurrentTCB->xNewLib_reent ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + } +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnEventList( List_t * const pxEventList, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH EITHER INTERRUPTS DISABLED OR THE + SCHEDULER SUSPENDED AND THE QUEUE BEING ACCESSED LOCKED. */ + + /* Place the event list item of the TCB in the appropriate event list. + This is placed in the list in priority order so the highest priority task + is the first to be woken by the event. The queue that contains the event + list is locked, preventing simultaneous access from interrupts. */ + vListInsert( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +void vTaskPlaceOnUnorderedEventList( List_t * pxEventList, const TickType_t xItemValue, const TickType_t xTicksToWait ) +{ + configASSERT( pxEventList ); + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event groups implementation. */ + configASSERT( uxSchedulerSuspended != 0 ); + + /* Store the item value in the event list item. It is safe to access the + event list item here as interrupts won't access the event list item of a + task that is not in the Blocked state. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Place the event list item of the TCB at the end of the appropriate event + list. It is safe to access the event list here because it is part of an + event group implementation - and interrupts don't access event groups + directly (instead they access them indirectly by pending function calls to + the task level). */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TIMERS == 1 ) + + void vTaskPlaceOnEventListRestricted( List_t * const pxEventList, TickType_t xTicksToWait, const BaseType_t xWaitIndefinitely ) + { + configASSERT( pxEventList ); + + /* This function should not be called by application code hence the + 'Restricted' in its name. It is not part of the public API. It is + designed for use by kernel code, and has special calling requirements - + it should be called with the scheduler suspended. */ + + + /* Place the event list item of the TCB in the appropriate event list. + In this case it is assume that this is the only task that is going to + be waiting on this event list, so the faster vListInsertEnd() function + can be used in place of vListInsert. */ + vListInsertEnd( pxEventList, &( pxCurrentTCB->xEventListItem ) ); + + /* If the task should block indefinitely then set the block time to a + value that will be recognised as an indefinite delay inside the + prvAddCurrentTaskToDelayedList() function. */ + if( xWaitIndefinitely != pdFALSE ) + { + xTicksToWait = portMAX_DELAY; + } + + traceTASK_DELAY_UNTIL( ( xTickCount + xTicksToWait ) ); + prvAddCurrentTaskToDelayedList( xTicksToWait, xWaitIndefinitely ); + } + +#endif /* configUSE_TIMERS */ +/*-----------------------------------------------------------*/ + +BaseType_t xTaskRemoveFromEventList( const List_t * const pxEventList ) +{ +TCB_t *pxUnblockedTCB; +BaseType_t xReturn; + + /* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be + called from a critical section within an ISR. */ + + /* The event list is sorted in priority order, so the first in the list can + be removed as it is known to be the highest priority. Remove the TCB from + the delayed list, and add it to the ready list. + + If an event is for a queue that is locked then this function will never + get called - the lock count on the queue will get modified instead. This + means exclusive access to the event list is guaranteed here. + + This function assumes that a check has already been made to ensure that + pxEventList is not empty. */ + pxUnblockedTCB = listGET_OWNER_OF_HEAD_ENTRY( pxEventList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( &( pxUnblockedTCB->xEventListItem ) ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked on a kernel object then xNextTaskUnblockTime + might be set to the blocked task's time out time. If the task is + unblocked for a reason other than a timeout xNextTaskUnblockTime is + normally left unchanged, because it is automatically reset to a new + value when the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter sleep mode + at the earliest possible time - so reset xNextTaskUnblockTime here to + ensure it is updated at the earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + } + else + { + /* The delayed and ready lists cannot be accessed, so hold this task + pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxUnblockedTCB->xEventListItem ) ); + } + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* Return true if the task removed from the event list has a higher + priority than the calling task. This allows the calling task to know if + it should force a context switch now. */ + xReturn = pdTRUE; + + /* Mark that a yield is pending in case the user is not using the + "xHigherPriorityTaskWoken" parameter to an ISR safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + xReturn = pdFALSE; + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskRemoveFromUnorderedEventList( ListItem_t * pxEventListItem, const TickType_t xItemValue ) +{ +TCB_t *pxUnblockedTCB; + + /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. It is used by + the event flags implementation. */ + configASSERT( uxSchedulerSuspended != pdFALSE ); + + /* Store the new item value in the event list. */ + listSET_LIST_ITEM_VALUE( pxEventListItem, xItemValue | taskEVENT_LIST_ITEM_VALUE_IN_USE ); + + /* Remove the event list form the event flag. Interrupts do not access + event flags. */ + pxUnblockedTCB = listGET_LIST_ITEM_OWNER( pxEventListItem ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + configASSERT( pxUnblockedTCB ); + ( void ) uxListRemove( pxEventListItem ); + + /* Remove the task from the delayed list and add it to the ready list. The + scheduler is suspended so interrupts will not be accessing the ready + lists. */ + ( void ) uxListRemove( &( pxUnblockedTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxUnblockedTCB ); + + if( pxUnblockedTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The unblocked task has a priority above that of the calling task, so + a context switch is required. This function is called with the + scheduler suspended so xYieldPending is set so the context switch + occurs immediately that the scheduler is resumed (unsuspended). */ + xYieldPending = pdTRUE; + } +} +/*-----------------------------------------------------------*/ + +void vTaskSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + configASSERT( pxTimeOut ); + taskENTER_CRITICAL(); + { + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +void vTaskInternalSetTimeOutState( TimeOut_t * const pxTimeOut ) +{ + /* For internal use only as it does not use a critical section. */ + pxTimeOut->xOverflowCount = xNumOfOverflows; + pxTimeOut->xTimeOnEntering = xTickCount; +} +/*-----------------------------------------------------------*/ + +BaseType_t xTaskCheckForTimeOut( TimeOut_t * const pxTimeOut, TickType_t * const pxTicksToWait ) +{ +BaseType_t xReturn; + + configASSERT( pxTimeOut ); + configASSERT( pxTicksToWait ); + + taskENTER_CRITICAL(); + { + /* Minor optimisation. The tick count cannot change in this block. */ + const TickType_t xConstTickCount = xTickCount; + const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + if( pxCurrentTCB->ucDelayAborted != ( uint8_t ) pdFALSE ) + { + /* The delay was aborted, which is not the same as a time out, + but has the same result. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + xReturn = pdTRUE; + } + else + #endif + + #if ( INCLUDE_vTaskSuspend == 1 ) + if( *pxTicksToWait == portMAX_DELAY ) + { + /* If INCLUDE_vTaskSuspend is set to 1 and the block time + specified is the maximum block time then the task should block + indefinitely, and therefore never time out. */ + xReturn = pdFALSE; + } + else + #endif + + if( ( xNumOfOverflows != pxTimeOut->xOverflowCount ) && ( xConstTickCount >= pxTimeOut->xTimeOnEntering ) ) /*lint !e525 Indentation preferred as is to make code within pre-processor directives clearer. */ + { + /* The tick count is greater than the time at which + vTaskSetTimeout() was called, but has also overflowed since + vTaskSetTimeOut() was called. It must have wrapped all the way + around and gone past again. This passed since vTaskSetTimeout() + was called. */ + xReturn = pdTRUE; + } + else if( xElapsedTime < *pxTicksToWait ) /*lint !e961 Explicit casting is only redundant with some compilers, whereas others require it to prevent integer conversion errors. */ + { + /* Not a genuine timeout. Adjust parameters for time remaining. */ + *pxTicksToWait -= xElapsedTime; + vTaskInternalSetTimeOutState( pxTimeOut ); + xReturn = pdFALSE; + } + else + { + *pxTicksToWait = 0; + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} +/*-----------------------------------------------------------*/ + +void vTaskMissedYield( void ) +{ + xYieldPending = pdTRUE; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) + { + UBaseType_t uxReturn; + TCB_t const *pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + uxReturn = pxTCB->uxTaskNumber; + } + else + { + uxReturn = 0U; + } + + return uxReturn; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTaskSetTaskNumber( TaskHandle_t xTask, const UBaseType_t uxHandle ) + { + TCB_t * pxTCB; + + if( xTask != NULL ) + { + pxTCB = xTask; + pxTCB->uxTaskNumber = uxHandle; + } + } + +#endif /* configUSE_TRACE_FACILITY */ + +/* + * ----------------------------------------------------------- + * The Idle task. + * ---------------------------------------------------------- + * + * The portTASK_FUNCTION() macro is used to allow port/compiler specific + * language extensions. The equivalent prototype for this function is: + * + * void prvIdleTask( void *pvParameters ); + * + */ +static portTASK_FUNCTION( prvIdleTask, pvParameters ) +{ + /* Stop warnings. */ + ( void ) pvParameters; + + /** THIS IS THE RTOS IDLE TASK - WHICH IS CREATED AUTOMATICALLY WHEN THE + SCHEDULER IS STARTED. **/ + + /* In case a task that has a secure context deletes itself, in which case + the idle task is responsible for deleting the task's secure context, if + any. */ + portALLOCATE_SECURE_CONTEXT( configMINIMAL_SECURE_STACK_SIZE ); + + for( ;; ) + { + /* See if any tasks have deleted themselves - if so then the idle task + is responsible for freeing the deleted task's TCB and stack. */ + prvCheckTasksWaitingTermination(); + + #if ( configUSE_PREEMPTION == 0 ) + { + /* If we are not using preemption we keep forcing a task switch to + see if any other task has become available. If we are using + preemption we don't need to do this as any task becoming available + will automatically get the processor anyway. */ + taskYIELD(); + } + #endif /* configUSE_PREEMPTION */ + + #if ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) + { + /* When using preemption tasks of equal priority will be + timesliced. If a task that is sharing the idle priority is ready + to run then the idle task should yield before the end of the + timeslice. + + A critical region is not required here as we are just reading from + the list, and an occasional incorrect value will not matter. If + the ready list at the idle priority contains more than one task + then a task other than the idle task is ready to execute. */ + if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists[ tskIDLE_PRIORITY ] ) ) > ( UBaseType_t ) 1 ) + { + taskYIELD(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* ( ( configUSE_PREEMPTION == 1 ) && ( configIDLE_SHOULD_YIELD == 1 ) ) */ + + #if ( configUSE_IDLE_HOOK == 1 ) + { + /* EST: Use user hook name */ + extern void configUSE_IDLE_HOOK_NAME( void ); + + /* Call the user defined function from within the idle task. This + allows the application designer to add background functionality + without the overhead of a separate task. + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, + CALL A FUNCTION THAT MIGHT BLOCK. */ + configUSE_IDLE_HOOK_NAME(); + } + #endif /* configUSE_IDLE_HOOK */ + + /* This conditional compilation should use inequality to 0, not equality + to 1. This is to ensure portSUPPRESS_TICKS_AND_SLEEP() is called when + user defined low power mode implementations require + configUSE_TICKLESS_IDLE to be set to a value other than 1. */ + #if ( configUSE_TICKLESS_IDLE != 0 ) + #if configUSE_TICKLESS_IDLE_DECISION_HOOK /* << EST */ + if (configUSE_TICKLESS_IDLE_DECISION_HOOK_NAME()) /* ask application if it shall enter tickless idle mode */ + #endif + { + TickType_t xExpectedIdleTime; + + /* It is not desirable to suspend then resume the scheduler on + each iteration of the idle task. Therefore, a preliminary + test of the expected idle time is performed without the + scheduler suspended. The result here is not necessarily + valid. */ + xExpectedIdleTime = prvGetExpectedIdleTime(); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + vTaskSuspendAll(); + { + /* Now the scheduler is suspended, the expected idle + time can be sampled again, and this time its value can + be used. */ + configASSERT( xNextTaskUnblockTime >= xTickCount ); + xExpectedIdleTime = prvGetExpectedIdleTime(); + + /* Define the following macro to set xExpectedIdleTime to 0 + if the application does not want + portSUPPRESS_TICKS_AND_SLEEP() to be called. */ + configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); + + if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) + { + traceLOW_POWER_IDLE_BEGIN(); + portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ); + traceLOW_POWER_IDLE_END(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + ( void ) xTaskResumeAll(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configUSE_TICKLESS_IDLE */ + } +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TICKLESS_IDLE != 0 ) + + eSleepModeStatus eTaskConfirmSleepModeStatus( void ) + { + /* The idle task exists in addition to the application tasks. */ + const UBaseType_t uxNonApplicationTasks = 1; + eSleepModeStatus eReturn = eStandardSleep; + + if( listCURRENT_LIST_LENGTH( &xPendingReadyList ) != 0 ) + { + /* A task was made ready while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else if( xYieldPending != pdFALSE ) + { + /* A yield was pended while the scheduler was suspended. */ + eReturn = eAbortSleep; + } + else + { + /* If all the tasks are in the suspended list (which might mean they + have an infinite block time rather than actually being suspended) + then it is safe to turn all clocks off and just wait for external + interrupts. */ + if( listCURRENT_LIST_LENGTH( &xSuspendedTaskList ) == ( uxCurrentNumberOfTasks - uxNonApplicationTasks ) ) + { + eReturn = eNoTasksWaitingTimeout; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + return eReturn; + } + +#endif /* configUSE_TICKLESS_IDLE */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void vTaskSetThreadLocalStoragePointer( TaskHandle_t xTaskToSet, BaseType_t xIndex, void *pvValue ) + { + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToSet ); + pxTCB->pvThreadLocalStoragePointers[ xIndex ] = pvValue; + } + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS != 0 ) + + void *pvTaskGetThreadLocalStoragePointer( TaskHandle_t xTaskToQuery, BaseType_t xIndex ) + { + void *pvReturn = NULL; + TCB_t *pxTCB; + + if( xIndex < configNUM_THREAD_LOCAL_STORAGE_POINTERS ) + { + pxTCB = prvGetTCBFromHandle( xTaskToQuery ); + pvReturn = pxTCB->pvThreadLocalStoragePointers[ xIndex ]; + } + else + { + pvReturn = NULL; + } + + return pvReturn; + } + +#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS */ +/*-----------------------------------------------------------*/ + +#if ( portUSING_MPU_WRAPPERS == 1 ) + + void vTaskAllocateMPURegions( TaskHandle_t xTaskToModify, const MemoryRegion_t * const xRegions ) + { + TCB_t *pxTCB; + + /* If null is passed in here then we are modifying the MPU settings of + the calling task. */ + pxTCB = prvGetTCBFromHandle( xTaskToModify ); + + vPortStoreTaskMPUSettings( &( pxTCB->xMPUSettings ), xRegions, NULL, 0 ); + } + +#endif /* portUSING_MPU_WRAPPERS */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseTaskLists( void ) +{ +UBaseType_t uxPriority; + + for( uxPriority = ( UBaseType_t ) 0U; uxPriority < ( UBaseType_t ) configMAX_PRIORITIES; uxPriority++ ) + { + vListInitialise( &( pxReadyTasksLists[ uxPriority ] ) ); + } + + vListInitialise( &xDelayedTaskList1 ); + vListInitialise( &xDelayedTaskList2 ); + vListInitialise( &xPendingReadyList ); + + #if ( INCLUDE_vTaskDelete == 1 ) + { + vListInitialise( &xTasksWaitingTermination ); + } + #endif /* INCLUDE_vTaskDelete */ + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + vListInitialise( &xSuspendedTaskList ); + } + #endif /* INCLUDE_vTaskSuspend */ + + /* Start with pxDelayedTaskList using list1 and the pxOverflowDelayedTaskList + using list2. */ + pxDelayedTaskList = &xDelayedTaskList1; + pxOverflowDelayedTaskList = &xDelayedTaskList2; +} +/*-----------------------------------------------------------*/ + +static void prvCheckTasksWaitingTermination( void ) +{ + + /** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/ + + #if ( INCLUDE_vTaskDelete == 1 ) + { + TCB_t *pxTCB; + + /* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL() + being called too often in the idle task. */ + while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) + { + taskENTER_CRITICAL(); + { + pxTCB = listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + --uxCurrentNumberOfTasks; + --uxDeletedTasksWaitingCleanUp; + } + taskEXIT_CRITICAL(); + + prvDeleteTCB( pxTCB ); + } + } + #endif /* INCLUDE_vTaskDelete */ +} +/*-----------------------------------------------------------*/ + +#if( configUSE_TRACE_FACILITY == 1 ) + + void vTaskGetInfo( TaskHandle_t xTask, TaskStatus_t *pxTaskStatus, BaseType_t xGetFreeStackSpace, eTaskState eState ) + { + TCB_t *pxTCB; + + /* xTask is NULL then get the state of the calling task. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + pxTaskStatus->xHandle = ( TaskHandle_t ) pxTCB; + pxTaskStatus->pcTaskName = ( const char * ) &( pxTCB->pcTaskName [ 0 ] ); + pxTaskStatus->uxCurrentPriority = pxTCB->uxPriority; + pxTaskStatus->pxStackBase = pxTCB->pxStack; + pxTaskStatus->xTaskNumber = pxTCB->uxTCBNumber; + + #if ( configUSE_MUTEXES == 1 ) + { + pxTaskStatus->uxBasePriority = pxTCB->uxBasePriority; + } + #else + { + pxTaskStatus->uxBasePriority = 0; + } + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + { + pxTaskStatus->ulRunTimeCounter = pxTCB->ulRunTimeCounter; + } + #else + { + pxTaskStatus->ulRunTimeCounter = 0; + } + #endif + + /* Obtaining the task state is a little fiddly, so is only done if the + value of eState passed into this function is eInvalid - otherwise the + state is just set to whatever is passed in. */ + if( eState != eInvalid ) + { + if( pxTCB == pxCurrentTCB ) + { + pxTaskStatus->eCurrentState = eRunning; + } + else + { + pxTaskStatus->eCurrentState = eState; + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* If the task is in the suspended list then there is a + chance it is actually just blocked indefinitely - so really + it should be reported as being in the Blocked state. */ + if( eState == eSuspended ) + { + vTaskSuspendAll(); + { + if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) + { + pxTaskStatus->eCurrentState = eBlocked; + } + } + ( void ) xTaskResumeAll(); + } + } + #endif /* INCLUDE_vTaskSuspend */ + } + } + else + { + pxTaskStatus->eCurrentState = eTaskGetState( pxTCB ); + } + + /* Obtaining the stack space takes some time, so the xGetFreeStackSpace + parameter is provided to allow it to be skipped. */ + if( xGetFreeStackSpace != pdFALSE ) + { + #if ( portSTACK_GROWTH > 0 ) + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxEndOfStack ); + } + #else + { + pxTaskStatus->usStackHighWaterMark = prvTaskCheckFreeStackSpace( ( uint8_t * ) pxTCB->pxStack ); + } + #endif + } + else + { + pxTaskStatus->usStackHighWaterMark = 0; + } + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + static UBaseType_t prvListTasksWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState ) + { + configLIST_VOLATILE TCB_t *pxNextTCB, *pxFirstTCB; + UBaseType_t uxTask = 0; + + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Populate an TaskStatus_t structure within the + pxTaskStatusArray array for each task that is referenced from + pxList. See the definition of TaskStatus_t in task.h for the + meaning of each TaskStatus_t structure member. */ + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + vTaskGetInfo( ( TaskHandle_t ) pxNextTCB, &( pxTaskStatusArray[ uxTask ] ), pdTRUE, eState ); + uxTask++; + } while( pxNextTCB != pxFirstTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return uxTask; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) + + static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) + { + uint32_t ulCount = 0U; + + while( *pucStackByte == ( uint8_t ) tskSTACK_FILL_BYTE ) + { + pucStackByte -= portSTACK_GROWTH; + ulCount++; + } + + ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */ + + return ( configSTACK_DEPTH_TYPE ) ulCount; + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark2 == 1 ) + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are the + same except for their return type. Using configSTACK_DEPTH_TYPE allows the + user to determine the return type. It gets around the problem of the value + overflowing on 8-bit types without breaking backward compatibility for + applications that expect an 8-bit return type. */ + configSTACK_DEPTH_TYPE uxTaskGetStackHighWaterMark2( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + configSTACK_DEPTH_TYPE uxReturn; + + /* uxTaskGetStackHighWaterMark() and uxTaskGetStackHighWaterMark2() are + the same except for their return type. Using configSTACK_DEPTH_TYPE + allows the user to determine the return type. It gets around the + problem of the value overflowing on 8-bit types without breaking + backward compatibility for applications that expect an 8-bit return + type. */ + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark2 */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) + + UBaseType_t uxTaskGetStackHighWaterMark( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + uint8_t *pucEndOfStack; + UBaseType_t uxReturn; + + pxTCB = prvGetTCBFromHandle( xTask ); + + #if portSTACK_GROWTH < 0 + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxStack; + } + #else + { + pucEndOfStack = ( uint8_t * ) pxTCB->pxEndOfStack; + } + #endif + + uxReturn = ( UBaseType_t ) prvTaskCheckFreeStackSpace( pucEndOfStack ); + + return uxReturn; + } + +#endif /* INCLUDE_uxTaskGetStackHighWaterMark */ +/*-----------------------------------------------------------*/ + +#if ( INCLUDE_vTaskDelete == 1 ) + + static void prvDeleteTCB( TCB_t *pxTCB ) + { + /* This call is required specifically for the TriCore port. It must be + above the vPortFree() calls. The call is also used by ports/demos that + want to allocate and clean RAM statically. */ + portCLEAN_UP_TCB( pxTCB ); + + /* Free up the memory allocated by the scheduler for the task. It is up + to the task to free any memory allocated at the application level. */ + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + { + _reclaim_reent( &( pxTCB->xNewLib_reent ) ); + } + #endif /* configUSE_NEWLIB_REENTRANT */ + + #if( ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 0 ) && ( portUSING_MPU_WRAPPERS == 0 ) ) + { + /* The task can only have been allocated dynamically - free both + the stack and TCB. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + #elif( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + { + /* The task could have been allocated statically or dynamically, so + check what was statically allocated before trying to free the + memory. */ + if( pxTCB->ucStaticallyAllocated == tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB ) + { + /* Both the stack and TCB were allocated dynamically, so both + must be freed. */ + vPortFree( pxTCB->pxStack ); + vPortFree( pxTCB ); + } + else if( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_ONLY ) + { + /* Only the stack was statically allocated, so the TCB is the + only memory that must be freed. */ + vPortFree( pxTCB ); + } + else + { + /* Neither the stack nor the TCB were allocated dynamically, so + nothing needs to be freed. */ + configASSERT( pxTCB->ucStaticallyAllocated == tskSTATICALLY_ALLOCATED_STACK_AND_TCB ); + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + } + +#endif /* INCLUDE_vTaskDelete */ +/*-----------------------------------------------------------*/ + +static void prvResetNextTaskUnblockTime( void ) +{ +TCB_t *pxTCB; + + if( listLIST_IS_EMPTY( pxDelayedTaskList ) != pdFALSE ) + { + /* The new current delayed list is empty. Set xNextTaskUnblockTime to + the maximum possible value so it is extremely unlikely that the + if( xTickCount >= xNextTaskUnblockTime ) test will pass until + there is an item in the delayed list. */ + xNextTaskUnblockTime = portMAX_DELAY; + } + else + { + /* The new current delayed list is not empty, get the value of + the item at the head of the delayed list. This is the time at + which the task at the head of the delayed list should be removed + from the Blocked state. */ + ( pxTCB ) = listGET_OWNER_OF_HEAD_ENTRY( pxDelayedTaskList ); /*lint !e9079 void * is used as this macro is used with timers and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + xNextTaskUnblockTime = listGET_LIST_ITEM_VALUE( &( ( pxTCB )->xStateListItem ) ); + } +} +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) + + TaskHandle_t xTaskGetCurrentTaskHandle( void ) + { + TaskHandle_t xReturn; + + /* A critical section is not required as this is not called from + an interrupt and the current TCB will always be the same for any + individual execution thread. */ + xReturn = pxCurrentTCB; + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetCurrentTaskHandle == 1 ) || ( configUSE_MUTEXES == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) + + BaseType_t xTaskGetSchedulerState( void ) + { + BaseType_t xReturn; + + if( xSchedulerRunning == pdFALSE ) + { + xReturn = taskSCHEDULER_NOT_STARTED; + } + else + { + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + xReturn = taskSCHEDULER_RUNNING; + } + else + { + xReturn = taskSCHEDULER_SUSPENDED; + } + } + + return xReturn; + } + +#endif /* ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityInherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxMutexHolderTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + /* If the mutex was given back by an interrupt while the queue was + locked then the mutex holder might now be NULL. _RB_ Is this still + needed as interrupts can no longer use mutexes? */ + if( pxMutexHolder != NULL ) + { + /* If the holder of the mutex has a priority below the priority of + the task attempting to obtain the mutex then it will temporarily + inherit the priority of the task attempting to obtain the mutex. */ + if( pxMutexHolderTCB->uxPriority < pxCurrentTCB->uxPriority ) + { + /* Adjust the mutex holder state to account for its new + priority. Only reset the event list item value if the value is + not being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxMutexHolderTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the task being modified is in the ready state it will need + to be moved into a new list. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ pxMutexHolderTCB->uxPriority ] ), &( pxMutexHolderTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxMutexHolderTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxMutexHolderTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Inherit the priority before being moved into the new list. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxMutexHolderTCB ); +#else + prvAddTaskToReadyList( pxMutexHolderTCB ); +#endif + } + else + { + /* Just inherit the priority. */ + pxMutexHolderTCB->uxPriority = pxCurrentTCB->uxPriority; + } + + traceTASK_PRIORITY_INHERIT( pxMutexHolderTCB, pxCurrentTCB->uxPriority ); + + /* Inheritance occurred. */ + xReturn = pdTRUE; + } + else + { + if( pxMutexHolderTCB->uxBasePriority < pxCurrentTCB->uxPriority ) + { + /* The base priority of the mutex holder is lower than the + priority of the task attempting to take the mutex, but the + current priority of the mutex holder is not lower than the + priority of the task attempting to take the mutex. + Therefore the mutex holder must have already inherited a + priority, but inheritance would have occurred if that had + not been the case. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) + { + TCB_t * const pxTCB = pxMutexHolder; + BaseType_t xReturn = pdFALSE; + + if( pxMutexHolder != NULL ) + { + /* A task can only have an inherited priority if it holds the mutex. + If the mutex is held by a task then it cannot be given from an + interrupt, and if a mutex is given by the holding task then it must + be the running state task. */ + configASSERT( pxTCB == pxCurrentTCB ); + configASSERT( pxTCB->uxMutexesHeld ); + ( pxTCB->uxMutexesHeld )--; + + /* Has the holder of the mutex inherited the priority of another + task? */ + if( pxTCB->uxPriority != pxTCB->uxBasePriority ) + { + /* Only disinherit if no other mutexes are held. */ + if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 ) + { + /* A task can only have an inherited priority if it holds + the mutex. If the mutex is held by a task then it cannot be + given from an interrupt, and if a mutex is given by the + holding task then it must be the running state task. Remove + the holding task from the ready list. */ + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Disinherit the priority before adding the task into the + new ready list. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + pxTCB->uxPriority = pxTCB->uxBasePriority; + + /* Reset the event list item value. It cannot be in use for + any other purpose if this task is running, and it must be + running to give back the mutex. */ + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxTCB->uxPriority ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ +#if configUSE_SEGGER_SYSTEM_VIEWER_HOOKS /* << EST */ + prvReAddTaskToReadyList( pxTCB ); +#else + prvAddTaskToReadyList( pxTCB ); +#endif + + /* Return true to indicate that a context switch is required. + This is only actually required in the corner case whereby + multiple mutexes were held and the mutexes were given back + in an order different to that in which they were taken. + If a context switch did not occur when the first mutex was + returned, even if a task was waiting on it, then a context + switch should occur when the last mutex is returned whether + a task is waiting on it or not. */ + xReturn = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + void vTaskPriorityDisinheritAfterTimeout( TaskHandle_t const pxMutexHolder, UBaseType_t uxHighestPriorityWaitingTask ) + { + TCB_t * const pxTCB = pxMutexHolder; + UBaseType_t uxPriorityUsedOnEntry, uxPriorityToUse; + const UBaseType_t uxOnlyOneMutexHeld = ( UBaseType_t ) 1; + + if( pxMutexHolder != NULL ) + { + /* If pxMutexHolder is not NULL then the holder must hold at least + one mutex. */ + configASSERT( pxTCB->uxMutexesHeld ); + + /* Determine the priority to which the priority of the task that + holds the mutex should be set. This will be the greater of the + holding task's base priority and the priority of the highest + priority task that is waiting to obtain the mutex. */ + if( pxTCB->uxBasePriority < uxHighestPriorityWaitingTask ) + { + uxPriorityToUse = uxHighestPriorityWaitingTask; + } + else + { + uxPriorityToUse = pxTCB->uxBasePriority; + } + + /* Does the priority need to change? */ + if( pxTCB->uxPriority != uxPriorityToUse ) + { + /* Only disinherit if no other mutexes are held. This is a + simplification in the priority inheritance implementation. If + the task that holds the mutex is also holding other mutexes then + the other mutexes may have caused the priority inheritance. */ + if( pxTCB->uxMutexesHeld == uxOnlyOneMutexHeld ) + { + /* If a task has timed out because it already holds the + mutex it was trying to obtain then it cannot of inherited + its own priority. */ + configASSERT( pxTCB != pxCurrentTCB ); + + /* Disinherit the priority, remembering the previous + priority to facilitate determining the subject task's + state. */ + traceTASK_PRIORITY_DISINHERIT( pxTCB, pxTCB->uxBasePriority ); + uxPriorityUsedOnEntry = pxTCB->uxPriority; + pxTCB->uxPriority = uxPriorityToUse; + + /* Only reset the event list item value if the value is not + being used for anything else. */ + if( ( listGET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ) ) & taskEVENT_LIST_ITEM_VALUE_IN_USE ) == 0UL ) + { + listSET_LIST_ITEM_VALUE( &( pxTCB->xEventListItem ), ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) uxPriorityToUse ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* If the running task is not the task that holds the mutex + then the task that holds the mutex could be in either the + Ready, Blocked or Suspended states. Only remove the task + from its current state list if it is in the Ready state as + the task's priority is going to change and there is one + Ready list per priority. */ + if( listIS_CONTAINED_WITHIN( &( pxReadyTasksLists[ uxPriorityUsedOnEntry ] ), &( pxTCB->xStateListItem ) ) != pdFALSE ) + { + if( uxListRemove( &( pxTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + taskRESET_READY_PRIORITY( pxTCB->uxPriority ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + prvAddTaskToReadyList( pxTCB ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskEnterCritical( void ) + { + portDISABLE_INTERRUPTS(); + + if( xSchedulerRunning != pdFALSE ) + { + ( pxCurrentTCB->uxCriticalNesting )++; + + /* This is not the interrupt safe version of the enter critical + function so assert() if it is being called from an interrupt + context. Only API functions that end in "FromISR" can be used in an + interrupt. Only assert if the critical nesting count is 1 to + protect against recursive calls if the assert function also uses a + critical section. */ + if( pxCurrentTCB->uxCriticalNesting == 1 ) + { + portASSERT_IF_IN_ISR(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( portCRITICAL_NESTING_IN_TCB == 1 ) + + void vTaskExitCritical( void ) + { + if( xSchedulerRunning != pdFALSE ) + { + if( pxCurrentTCB->uxCriticalNesting > 0U ) + { + ( pxCurrentTCB->uxCriticalNesting )--; + + if( pxCurrentTCB->uxCriticalNesting == 0U ) + { + portENABLE_INTERRUPTS(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* portCRITICAL_NESTING_IN_TCB */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) +#if 0 /* << EST: not used */ + static char *prvWriteNameToBuffer( char *pcBuffer, const char *pcTaskName ) + { + size_t x; + + /* Start by copying the entire string. */ + strcpy( pcBuffer, pcTaskName ); + + /* Pad the end of the string with spaces to ensure columns line up when + printed out. */ + for( x = strlen( pcBuffer ); x < ( size_t ) ( configMAX_TASK_NAME_LEN - 1 ); x++ ) + { + pcBuffer[ x ] = ' '; + } + + /* Terminate. */ + pcBuffer[ x ] = ( char ) 0x00; + + /* Return the new end of string. */ + return &( pcBuffer[ x ] ); + } +#endif /* << EST not used */ +#endif /* ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) */ +/*-----------------------------------------------------------*/ + +#if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskList( char * pcWriteBuffer, size_t bufSize ) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + char cStatus; + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskList() calls uxTaskGetSystemState(), then formats part of the + * uxTaskGetSystemState() output into a human readable table that + * displays task names, states and stack usage. + * + * vTaskList() has a dependency on the sprintf() C library function that + * might bloat the code size, use a lot of stack, and provide different + * results on different platforms. An alternative, tiny, third party, + * and limited functionality implementation of sprintf() is provided in + * many of the FreeRTOS/Demo sub-directories in a file called + * printf-stdarg.c (note printf-stdarg.c does not provide a full + * snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskList(). + */ + + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! if + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, NULL ); + + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + switch( pxTaskStatusArray[ x ].eCurrentState ) + { + case eRunning: cStatus = tskRUNNING_CHAR; + break; + + case eReady: cStatus = tskREADY_CHAR; + break; + + case eBlocked: cStatus = tskBLOCKED_CHAR; + break; + + case eSuspended: cStatus = tskSUSPENDED_CHAR; + break; + + case eDeleted: cStatus = tskDELETED_CHAR; + break; + + case eInvalid: /* Fall through. */ + default: /* Should not get here, but it is included + to prevent static checking errors. */ + cStatus = ( char ) 0x00; + break; + } + +#if 0 /* << EST */ + /* Write the task name to the string, padding with spaces so it + can be printed in tabular form more easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); + + /* Write the rest of the string. */ + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t\t%c\t%u\t%u\t%u\r\n", cStatus, ( unsigned int ) pxTaskStatusArray[ x ].uxCurrentPriority, ( unsigned int ) pxTaskStatusArray[ x ].usStackHighWaterMark, ( unsigned int ) pxTaskStatusArray[ x ].xTaskNumber ); + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#else /* << EST */ + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)cStatus); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].uxCurrentPriority); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].usStackHighWaterMark); + UTIL1_chcat((uint8_t*)pcWriteBuffer, bufSize, (unsigned char)'\t'); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].xTaskNumber); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\r\n"); +#endif + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) */ +/*----------------------------------------------------------*/ + +#if ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) + + void vTaskGetRunTimeStats( char *pcWriteBuffer, size_t bufSize) /* << EST */ + { + TaskStatus_t *pxTaskStatusArray; + UBaseType_t uxArraySize, x; + uint32_t ulTotalTime, ulStatsAsPercentage; + + #if( configUSE_TRACE_FACILITY != 1 ) + { + #error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats(). + } + #endif + + /* + * PLEASE NOTE: + * + * This function is provided for convenience only, and is used by many + * of the demo applications. Do not consider it to be part of the + * scheduler. + * + * vTaskGetRunTimeStats() calls uxTaskGetSystemState(), then formats part + * of the uxTaskGetSystemState() output into a human readable table that + * displays the amount of time each task has spent in the Running state + * in both absolute and percentage terms. + * + * vTaskGetRunTimeStats() has a dependency on the sprintf() C library + * function that might bloat the code size, use a lot of stack, and + * provide different results on different platforms. An alternative, + * tiny, third party, and limited functionality implementation of + * sprintf() is provided in many of the FreeRTOS/Demo sub-directories in + * a file called printf-stdarg.c (note printf-stdarg.c does not provide + * a full snprintf() implementation!). + * + * It is recommended that production systems call uxTaskGetSystemState() + * directly to get access to raw stats data, rather than indirectly + * through a call to vTaskGetRunTimeStats(). + */ + + /* Make sure the write buffer does not contain a string. */ + *pcWriteBuffer = ( char ) 0x00; + + /* Take a snapshot of the number of tasks in case it changes while this + function is executing. */ + uxArraySize = uxCurrentNumberOfTasks; + + /* Allocate an array index for each task. NOTE! If + configSUPPORT_DYNAMIC_ALLOCATION is set to 0 then pvPortMalloc() will + equate to NULL. */ + pxTaskStatusArray = pvPortMalloc( uxCurrentNumberOfTasks * sizeof( TaskStatus_t ) ); /*lint !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack and this allocation allocates a struct that has the alignment requirements of a pointer. */ + + if( pxTaskStatusArray != NULL ) + { + /* Generate the (binary) data. */ + uxArraySize = uxTaskGetSystemState( pxTaskStatusArray, uxArraySize, &ulTotalTime ); + + /* For percentage calculations. */ + ulTotalTime /= 100UL; + + /* Avoid divide by zero errors. */ + if( ulTotalTime > 0UL ) + { + /* Create a human readable table from the binary data. */ + for( x = 0; x < uxArraySize; x++ ) + { + /* What percentage of the total run time has the task used? + This will always be rounded down to the nearest integer. + ulTotalRunTimeDiv100 has already been divided by 100. */ + ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime; + +#if 0 /* << EST */ + /* Write the task name to the string, padding with + spaces so it can be printed in tabular form more + easily. */ + pcWriteBuffer = prvWriteNameToBuffer( pcWriteBuffer, pxTaskStatusArray[ x ].pcTaskName ); +#else + UTIL1_strcatPad((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)pxTaskStatusArray[ x ].pcTaskName, ' ', configMAX_TASK_NAME_LEN); +#endif + if( ulStatsAsPercentage > 0UL ) + { + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( ( char * ) pcWriteBuffer, ( char * ) "%s\t\t%lu\t\t%lu%%\r\n", pxTaskStatusArray[ x ].pcTaskName, pxTaskStatusArray[ x ].ulRunTimeCounter, ulStatsAsPercentage ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t%u%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter, ( unsigned int ) ulStatsAsPercentage ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, ulStatsAsPercentage); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"%\r\n"); +#endif + } + #endif + } + else + { + /* If the percentage is zero here then the task has + consumed less than 1% of the total run time. */ + #ifdef portLU_PRINTF_SPECIFIER_REQUIRED + { + sprintf( pcWriteBuffer, "\t%lu\t\t<1%%\r\n", pxTaskStatusArray[ x ].ulRunTimeCounter ); + } + #else + { + /* sizeof( int ) == sizeof( long ) so a smaller + printf() library can be used. */ +#if 0 + sprintf( ( char * ) pcWriteBuffer, ( char * ) "\t%u\t\t<1%%\r\n", ( unsigned int ) pxTaskStatusArray[ x ].ulRunTimeCounter ); +#else /* << EST */ + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t"); + UTIL1_strcatNum32u((uint8_t*)pcWriteBuffer, bufSize, pxTaskStatusArray[ x ].ulRunTimeCounter); + UTIL1_strcat((uint8_t*)pcWriteBuffer, bufSize, (const unsigned char*)"\t\t<1%\r\n"); +#endif + } + #endif + } +#if 0 /* << EST */ + pcWriteBuffer += strlen( pcWriteBuffer ); /*lint !e9016 Pointer arithmetic ok on char pointers especially as in this case where it best denotes the intent of the code. */ +#endif + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + /* Free the array again. NOTE! If configSUPPORT_DYNAMIC_ALLOCATION + is 0 then vPortFree() will be #defined to nothing. */ + vPortFree( pxTaskStatusArray ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + +#endif /* ( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) */ +/*-----------------------------------------------------------*/ + +TickType_t uxTaskResetEventItemValue( void ) +{ +TickType_t uxReturn; + + uxReturn = listGET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ) ); + + /* Reset the event list item to its normal value - so it can be used with + queues and semaphores. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xEventListItem ), ( ( TickType_t ) configMAX_PRIORITIES - ( TickType_t ) pxCurrentTCB->uxPriority ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + return uxReturn; +} +/*-----------------------------------------------------------*/ + +#if ( configUSE_MUTEXES == 1 ) + + TaskHandle_t pvTaskIncrementMutexHeldCount( void ) + { + /* If xSemaphoreCreateMutex() is called before any tasks have been created + then pxCurrentTCB will be NULL. */ + if( pxCurrentTCB != NULL ) + { + ( pxCurrentTCB->uxMutexesHeld )++; + } + + return pxCurrentTCB; + } + +#endif /* configUSE_MUTEXES */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + uint32_t ulTaskNotifyTake( BaseType_t xClearCountOnExit, TickType_t xTicksToWait ) + { + uint32_t ulReturn; + + taskENTER_CRITICAL(); + { + /* Only block if the notification count is not already non-zero. */ + if( pxCurrentTCB->ulNotifiedValue == 0UL ) + { + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_TAKE_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_TAKE(); + ulReturn = pxCurrentTCB->ulNotifiedValue; + + if( ulReturn != 0UL ) + { + if( xClearCountOnExit != pdFALSE ) + { + pxCurrentTCB->ulNotifiedValue = 0UL; + } + else + { + pxCurrentTCB->ulNotifiedValue = ulReturn - ( uint32_t ) 1; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return ulReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyWait( uint32_t ulBitsToClearOnEntry, uint32_t ulBitsToClearOnExit, uint32_t *pulNotificationValue, TickType_t xTicksToWait ) + { + BaseType_t xReturn; + + taskENTER_CRITICAL(); + { + /* Only block if a notification is not already pending. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* Clear bits in the task's notification value as bits may get + set by the notifying task or interrupt. This can be used to + clear the value to zero. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnEntry; + + /* Mark this task as waiting for a notification. */ + pxCurrentTCB->ucNotifyState = taskWAITING_NOTIFICATION; + + if( xTicksToWait > ( TickType_t ) 0 ) + { + prvAddCurrentTaskToDelayedList( xTicksToWait, pdTRUE ); + traceTASK_NOTIFY_WAIT_BLOCK(); + + /* All ports are written to allow a yield in a critical + section (some will yield immediately, others wait until the + critical section exits) - but it is not something that + application code should ever do. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + taskENTER_CRITICAL(); + { + traceTASK_NOTIFY_WAIT(); + + if( pulNotificationValue != NULL ) + { + /* Output the current notification value, which may or may not + have changed. */ + *pulNotificationValue = pxCurrentTCB->ulNotifiedValue; + } + + /* If ucNotifyValue is set then either the task never entered the + blocked state (because a notification was already pending) or the + task unblocked because of a notification. Otherwise the task + unblocked because of a timeout. */ + if( pxCurrentTCB->ucNotifyState != taskNOTIFICATION_RECEIVED ) + { + /* A notification was not received. */ + xReturn = pdFALSE; + } + else + { + /* A notification was already pending or a notification was + received while the task was waiting. */ + pxCurrentTCB->ulNotifiedValue &= ~ulBitsToClearOnExit; + xReturn = pdTRUE; + } + + pxCurrentTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotify( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue ) + { + TCB_t * pxTCB; + BaseType_t xReturn = pdPASS; + uint8_t ucOriginalNotifyState; + + configASSERT( xTaskToNotify ); + pxTCB = xTaskToNotify; + + taskENTER_CRITICAL(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction: + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + + break; + } + + traceTASK_NOTIFY(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + #if( configUSE_TICKLESS_IDLE != 0 ) + { + /* If a task is blocked waiting for a notification then + xNextTaskUnblockTime might be set to the blocked task's time + out time. If the task is unblocked for a reason other than + a timeout xNextTaskUnblockTime is normally left unchanged, + because it will automatically get reset to a new value when + the tick count equals xNextTaskUnblockTime. However if + tickless idling is used it might be more important to enter + sleep mode at the earliest possible time - so reset + xNextTaskUnblockTime here to ensure it is updated at the + earliest possible time. */ + prvResetNextTaskUnblockTime(); + } + #endif + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + taskYIELD_IF_USING_PREEMPTION(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskGenericNotifyFromISR( TaskHandle_t xTaskToNotify, uint32_t ulValue, eNotifyAction eAction, uint32_t *pulPreviousNotificationValue, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + BaseType_t xReturn = pdPASS; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + if( pulPreviousNotificationValue != NULL ) + { + *pulPreviousNotificationValue = pxTCB->ulNotifiedValue; + } + + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + switch( eAction ) + { + case eSetBits : + pxTCB->ulNotifiedValue |= ulValue; + break; + + case eIncrement : + ( pxTCB->ulNotifiedValue )++; + break; + + case eSetValueWithOverwrite : + pxTCB->ulNotifiedValue = ulValue; + break; + + case eSetValueWithoutOverwrite : + if( ucOriginalNotifyState != taskNOTIFICATION_RECEIVED ) + { + pxTCB->ulNotifiedValue = ulValue; + } + else + { + /* The value could not be written to the task. */ + xReturn = pdFAIL; + } + break; + + case eNoAction : + /* The task is being notified without its notify value being + updated. */ + break; + + default: + /* Should not get here if all enums are handled. + Artificially force an assert by testing a value the + compiler can't assume is const. */ + configASSERT( pxTCB->ulNotifiedValue == ~0UL ); + break; + } + + traceTASK_NOTIFY_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter to an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + void vTaskNotifyGiveFromISR( TaskHandle_t xTaskToNotify, BaseType_t *pxHigherPriorityTaskWoken ) + { + TCB_t * pxTCB; + uint8_t ucOriginalNotifyState; + UBaseType_t uxSavedInterruptStatus; + + configASSERT( xTaskToNotify ); + + /* RTOS ports that support interrupt nesting have the concept of a + maximum system call (or maximum API call) interrupt priority. + Interrupts that are above the maximum system call priority are keep + permanently enabled, even when the RTOS kernel is in a critical section, + but cannot make any calls to FreeRTOS API functions. If configASSERT() + is defined in FreeRTOSConfig.h then + portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion + failure if a FreeRTOS API function is called from an interrupt that has + been assigned a priority above the configured maximum system call + priority. Only FreeRTOS functions that end in FromISR can be called + from interrupts that have been assigned a priority at or (logically) + below the maximum system call interrupt priority. FreeRTOS maintains a + separate interrupt safe API to ensure interrupt entry is as fast and as + simple as possible. More information (albeit Cortex-M specific) is + provided on the following link: + http://www.freertos.org/RTOS-Cortex-M3-M4.html */ + portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); + + pxTCB = xTaskToNotify; + + uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); + { + ucOriginalNotifyState = pxTCB->ucNotifyState; + pxTCB->ucNotifyState = taskNOTIFICATION_RECEIVED; + + /* 'Giving' is equivalent to incrementing a count in a counting + semaphore. */ + ( pxTCB->ulNotifiedValue )++; + + traceTASK_NOTIFY_GIVE_FROM_ISR(); + + /* If the task is in the blocked state specifically to wait for a + notification then unblock it now. */ + if( ucOriginalNotifyState == taskWAITING_NOTIFICATION ) + { + /* The task should not have been on an event list. */ + configASSERT( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL ); + + if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE ) + { + ( void ) uxListRemove( &( pxTCB->xStateListItem ) ); + prvAddTaskToReadyList( pxTCB ); + } + else + { + /* The delayed and ready lists cannot be accessed, so hold + this task pending until the scheduler is resumed. */ + vListInsertEnd( &( xPendingReadyList ), &( pxTCB->xEventListItem ) ); + } + + if( pxTCB->uxPriority > pxCurrentTCB->uxPriority ) + { + /* The notified task has a priority above the currently + executing task so a yield is required. */ + if( pxHigherPriorityTaskWoken != NULL ) + { + *pxHigherPriorityTaskWoken = pdTRUE; + } + + /* Mark that a yield is pending in case the user is not + using the "xHigherPriorityTaskWoken" parameter in an ISR + safe FreeRTOS function. */ + xYieldPending = pdTRUE; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ + +/*-----------------------------------------------------------*/ + +#if( configUSE_TASK_NOTIFICATIONS == 1 ) + + BaseType_t xTaskNotifyStateClear( TaskHandle_t xTask ) + { + TCB_t *pxTCB; + BaseType_t xReturn; + + /* If null is passed in here then it is the calling task that is having + its notification state cleared. */ + pxTCB = prvGetTCBFromHandle( xTask ); + + taskENTER_CRITICAL(); + { + if( pxTCB->ucNotifyState == taskNOTIFICATION_RECEIVED ) + { + pxTCB->ucNotifyState = taskNOT_WAITING_NOTIFICATION; + xReturn = pdPASS; + } + else + { + xReturn = pdFAIL; + } + } + taskEXIT_CRITICAL(); + + return xReturn; + } + +#endif /* configUSE_TASK_NOTIFICATIONS */ +/*-----------------------------------------------------------*/ + +#if( ( configGENERATE_RUN_TIME_STATS == 1 ) && ( INCLUDE_xTaskGetIdleTaskHandle == 1 ) ) + TickType_t xTaskGetIdleRunTimeCounter( void ) + { + return xIdleTaskHandle->ulRunTimeCounter; + } +#endif +/*-----------------------------------------------------------*/ + +static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseType_t xCanBlockIndefinitely ) +{ +TickType_t xTimeToWake; +const TickType_t xConstTickCount = xTickCount; + + #if( INCLUDE_xTaskAbortDelay == 1 ) + { + /* About to enter a delayed list, so ensure the ucDelayAborted flag is + reset to pdFALSE so it can be detected as having been set to pdTRUE + when the task leaves the Blocked state. */ + pxCurrentTCB->ucDelayAborted = pdFALSE; + } + #endif + + /* Remove the task from the ready list before adding it to the blocked list + as the same list item is used for both lists. */ + if( uxListRemove( &( pxCurrentTCB->xStateListItem ) ) == ( UBaseType_t ) 0 ) + { + /* The current task must be in a ready list, so there is no need to + check, and the port reset macro can be called directly. */ + portRESET_READY_PRIORITY( pxCurrentTCB->uxPriority, uxTopReadyPriority ); /*lint !e931 pxCurrentTCB cannot change as it is the calling task. pxCurrentTCB->uxPriority and uxTopReadyPriority cannot change as called with scheduler suspended or in a critical section. */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + #if ( INCLUDE_vTaskSuspend == 1 ) + { + if( ( xTicksToWait == portMAX_DELAY ) && ( xCanBlockIndefinitely != pdFALSE ) ) + { + /* Add the task to the suspended task list instead of a delayed task + list to ensure it is not woken by a timing event. It will block + indefinitely. */ + traceMOVED_TASK_TO_SUSPENDED_LIST(pxCurrentTCB); /* << EST */ + vListInsertEnd( &xSuspendedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the + kernel will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow + list. */ + traceMOVED_TASK_TO_OVERFLOW_DELAYED_LIST(); /* << EST */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list + is used. */ + traceMOVED_TASK_TO_DELAYED_LIST(); /* << EST */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the + head of the list of blocked tasks then xNextTaskUnblockTime + needs to be updated too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + } + #else /* INCLUDE_vTaskSuspend */ + { + /* Calculate the time at which the task should be woken if the event + does not occur. This may overflow but this doesn't matter, the kernel + will manage it correctly. */ + xTimeToWake = xConstTickCount + xTicksToWait; + + /* The list item will be inserted in wake time order. */ + listSET_LIST_ITEM_VALUE( &( pxCurrentTCB->xStateListItem ), xTimeToWake ); + + if( xTimeToWake < xConstTickCount ) + { + /* Wake time has overflowed. Place this item in the overflow list. */ + vListInsert( pxOverflowDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + } + else + { + /* The wake time has not overflowed, so the current block list is used. */ + vListInsert( pxDelayedTaskList, &( pxCurrentTCB->xStateListItem ) ); + + /* If the task entering the blocked state was placed at the head of the + list of blocked tasks then xNextTaskUnblockTime needs to be updated + too. */ + if( xTimeToWake < xNextTaskUnblockTime ) + { + xNextTaskUnblockTime = xTimeToWake; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + /* Avoid compiler warning when INCLUDE_vTaskSuspend is not 1. */ + ( void ) xCanBlockIndefinitely; + } + #endif /* INCLUDE_vTaskSuspend */ +} + +/* Code below here allows additional code to be inserted into this source file, +especially where access to file scope functions and data is needed (for example +when performing module tests). */ + +#ifdef FREERTOS_MODULE_TEST + #include "tasks_test_access_functions.h" +#endif + + +#if( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 && configUSE_TRACE_FACILITY==1) /* << EST test on trace */ + + #include "freertos_tasks_c_additions.h" + + #ifdef FREERTOS_TASKS_C_ADDITIONS_INIT + static void freertos_tasks_c_additions_init( void ) + { + FREERTOS_TASKS_C_ADDITIONS_INIT(); + } + #endif + +#endif + +#if 1 /* << EST: additional functionality to iterathe through task handles. */ +static void prvCollectTaskHandlesWithinSingleList( List_t *pxList, TaskHandle_t taskHandleArray[], UBaseType_t noTaskHandlesInArray, UBaseType_t *idxCounter) +{ + TCB_t *pxNextTCB, *pxFirstTCB; + + /* This function is called with the scheduler suspended. */ + if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 ) + { + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + if (*idxCounter ( UBaseType_t ) tskIDLE_PRIORITY ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + + /* Search the delayed lists. */ + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + prvCollectTaskHandlesWithinSingleList( ( List_t * ) pxOverflowDelayedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + #if ( INCLUDE_vTaskSuspend == 1 ) + { + /* Search the suspended list. */ + prvCollectTaskHandlesWithinSingleList( &xSuspendedTaskList, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + #if( INCLUDE_vTaskDelete == 1 ) + { + /* Search the deleted list. */ + prvCollectTaskHandlesWithinSingleList( &xTasksWaitingTermination, pxTaskHandleArray, xNofTaskHandlesInArray, &idxCounter); + } + #endif + } + ( void ) xTaskResumeAll(); + return idxCounter; +} + +void vTaskGetStackInfo(TaskHandle_t xTask, StackType_t **ppxStart, StackType_t **ppxEnd, StackType_t **ppxTopOfStack, uint8_t *pucStaticallyAllocated) +{ + TCB_t *pxTCB; + + taskENTER_CRITICAL(); + { + /* If null is passed in here then it is the priority of the that + called uxTaskPriorityGet() that is being queried. */ + pxTCB = prvGetTCBFromHandle( xTask ); +#if ( portSTACK_GROWTH > 0 ) + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxEndOfStack; +#elif (configRECORD_STACK_HIGH_ADDRESS == 1) + *ppxStart = pxTCB->pxEndOfStack; + *ppxEnd = pxTCB->pxStack; +#else /* no stack end information, return a zero size */ + *ppxStart = pxTCB->pxStack; + *ppxEnd = pxTCB->pxStack; +#endif + *ppxTopOfStack = (StackType_t*)pxTCB->pxTopOfStack; +#if( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) + *pucStaticallyAllocated = pxTCB->ucStaticallyAllocated; +#elif (configSUPPORT_STATIC_ALLOCATION && !configSUPPORT_DYNAMIC_ALLOCATION) /* only static allocation */ + *pucStaticallyAllocated = tskSTATICALLY_ALLOCATED_STACK_AND_TCB; +#else /* only configSUPPORT_DYNAMIC_ALLOCATION */ + *pucStaticallyAllocated = tskDYNAMICALLY_ALLOCATED_STACK_AND_TCB; +#endif + } + taskEXIT_CRITICAL(); +} +#endif /* << EST end */ + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.c b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.c new file mode 100644 index 0000000..1199d32 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.c @@ -0,0 +1,1111 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + +/* Standard includes. */ +#include + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining +all the API functions to use the MPU wrappers. That should only be done when +task.h is included from an application file. */ +#define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#include "FreeRTOS.h" +#include "task.h" +#include "queue.h" +#include "timers.h" + +#if ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 0 ) + #error configUSE_TIMERS must be set to 1 to make the xTimerPendFunctionCall() function available. +#endif + +/* Lint e9021, e961 and e750 are suppressed as a MISRA exception justified +because the MPU ports require MPU_WRAPPERS_INCLUDED_FROM_API_FILE to be defined +for the header files above, but not in this file, in order to generate the +correct privileged Vs unprivileged linkage and placement. */ +#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e9021 !e961 !e750. */ + + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. This #if is closed at the very bottom +of this file. If you want to include software timer functionality then ensure +configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#if ( configUSE_TIMERS == 1 ) + +/* Misc definitions. */ +#define tmrNO_DELAY ( TickType_t ) 0U + +/* The name assigned to the timer service task. This can be overridden by +defining trmTIMER_SERVICE_TASK_NAME in FreeRTOSConfig.h. */ +#ifndef configTIMER_SERVICE_TASK_NAME + #define configTIMER_SERVICE_TASK_NAME "Tmr Svc" +#endif + +/* Bit definitions used in the ucStatus member of a timer structure. */ +#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) +#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) +#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + +#define TIMER_LEGACY_API (1) /* << EST: needed to have TAD working */ + +/* The definition of the timers themselves. */ +typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + const char *pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks;/*<< How quickly and often the timer expires. */ +#if TIMER_LEGACY_API /* << EST */ + UBaseType_t uxAutoReload; /*<< Set to pdTRUE if the timer should be automatically restarted once expired. Set to pdFALSE if the timer is, in effect, a one-shot timer. */ +#endif + void *pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ +} xTIMER; + +/* The old xTIMER name is maintained above then typedefed to the new Timer_t +name below to enable the use of older kernel aware debuggers. */ +typedef xTIMER Timer_t; + +/* The definition of messages that can be sent and received on the timer queue. +Two types of message can be queued - messages that manipulate a software timer, +and messages that request the execution of a non-timer related callback. The +two message types are defined in two separate structures, xTimerParametersType +and xCallbackParametersType respectively. */ +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void *pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +/* The structure that contains the two message types, along with an identifier +that is used to determine which message type is valid. */ +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + +/*lint -save -e956 A manual analysis and inspection has been used to determine +which static variables must be declared volatile. */ + +/* The list in which active timers are stored. Timers are referenced in expire +time order, with the nearest expiry time at the front of the list. Only the +timer service task is allowed to access these lists. +xActiveTimerList1 and xActiveTimerList2 could be at function scope but that +breaks some kernel aware debuggers, and debuggers that reply on removing the +static qualifier. */ +PRIVILEGED_DATA static List_t xActiveTimerList1; +PRIVILEGED_DATA static List_t xActiveTimerList2; +PRIVILEGED_DATA static List_t *pxCurrentTimerList; +PRIVILEGED_DATA static List_t *pxOverflowTimerList; + +/* A queue that is used to send commands to the timer service task. */ +PRIVILEGED_DATA static QueueHandle_t xTimerQueue = NULL; +PRIVILEGED_DATA static TaskHandle_t xTimerTaskHandle = NULL; + +/*lint -restore */ + +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + /* If static allocation is supported then the application must provide the + following callback function - which enables the application to optionally + provide the memory that will be used by the timer task as the task's stack + and TCB. */ + extern void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize ); + +#endif + +/* + * Initialise the infrastructure used by the timer service task if it has not + * been initialised already. + */ +static void prvCheckForValidListAndQueue( void ) PRIVILEGED_FUNCTION; + +/* + * The timer service task (daemon). Timer functionality is controlled by this + * task. Other tasks communicate with the timer service task using the + * xTimerQueue queue. + */ +static portTASK_FUNCTION_PROTO( prvTimerTask, pvParameters ) PRIVILEGED_FUNCTION; + +/* + * Called by the timer service task to interpret and process a command it + * received on the timer queue. + */ +static void prvProcessReceivedCommands( void ) PRIVILEGED_FUNCTION; + +/* + * Insert the timer into either xActiveTimerList1, or xActiveTimerList2, + * depending on if the expire time causes a timer counter overflow. + */ +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) PRIVILEGED_FUNCTION; + +/* + * An active timer has reached its expire time. Reload the timer if it is an + * auto reload timer, then call its callback. + */ +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) PRIVILEGED_FUNCTION; + +/* + * The tick count has overflowed. Switch the timer lists after ensuring the + * current timer list does not still reference some timers. + */ +static void prvSwitchTimerLists( void ) PRIVILEGED_FUNCTION; + +/* + * Obtain the current tick count, setting *pxTimerListsWereSwitched to pdTRUE + * if a tick count overflow occurred since prvSampleTimeNow() was last called. + */ +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) PRIVILEGED_FUNCTION; + +/* + * If the timer list contains any active timers then return the expire time of + * the timer that will expire first and set *pxListWasEmpty to false. If the + * timer list does not contain any timers then return 0 and set *pxListWasEmpty + * to pdTRUE. + */ +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * If a timer has expired, process it. Otherwise, block the timer service task + * until either a timer does expire or a command is received. + */ +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) PRIVILEGED_FUNCTION; + +/* + * Called after a Timer_t structure has been allocated either statically or + * dynamically to fill in the structure's members. + */ +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) PRIVILEGED_FUNCTION; +/*-----------------------------------------------------------*/ + +BaseType_t xTimerCreateTimerTask( void ) +{ +BaseType_t xReturn = pdFAIL; + + /* This function is called when the scheduler is started if + configUSE_TIMERS is set to 1. Check that the infrastructure used by the + timer service task has been created/initialised. If timers have already + been created then the initialisation will already have been performed. */ + prvCheckForValidListAndQueue(); + + if( xTimerQueue != NULL ) + { + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + StaticTask_t *pxTimerTaskTCBBuffer = NULL; + StackType_t *pxTimerTaskStackBuffer = NULL; + uint32_t ulTimerTaskStackSize; + + vApplicationGetTimerTaskMemory( &pxTimerTaskTCBBuffer, &pxTimerTaskStackBuffer, &ulTimerTaskStackSize ); + xTimerTaskHandle = xTaskCreateStatic( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + ulTimerTaskStackSize, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + pxTimerTaskStackBuffer, + pxTimerTaskTCBBuffer ); + + if( xTimerTaskHandle != NULL ) + { + xReturn = pdPASS; + } + } + #else + { + xReturn = xTaskCreate( prvTimerTask, + configTIMER_SERVICE_TASK_NAME, + configTIMER_TASK_STACK_DEPTH, + NULL, + ( ( UBaseType_t ) configTIMER_TASK_PRIORITY ) | portPRIVILEGE_BIT, + &xTimerTaskHandle ); + } + #endif /* configSUPPORT_STATIC_ALLOCATION */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + configASSERT( xReturn ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) + { + Timer_t *pxNewTimer; + + pxNewTimer = ( Timer_t * ) pvPortMalloc( sizeof( Timer_t ) ); /*lint !e9087 !e9079 All values returned by pvPortMalloc() have at least the alignment required by the MCU's stack, and the first member of Timer_t is always a pointer to the timer's mame. */ + + if( pxNewTimer != NULL ) + { + /* Status is thus far zero as the timer is not created statically + and has not been started. The autoreload bit may get set in + prvInitialiseNewTimer. */ + pxNewTimer->ucStatus = 0x00; + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_DYNAMIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) + { + Timer_t *pxNewTimer; + + #if( configASSERT_DEFINED == 1 ) + { + /* Sanity check that the size of the structure used to declare a + variable of type StaticTimer_t equals the size of the real timer + structure. */ + volatile size_t xSize = sizeof( StaticTimer_t ); + configASSERT( xSize == sizeof( Timer_t ) ); + ( void ) xSize; /* Keeps lint quiet when configASSERT() is not defined. */ + } + #endif /* configASSERT_DEFINED */ + + /* A pointer to a StaticTimer_t structure MUST be provided, use it. */ + configASSERT( pxTimerBuffer ); + pxNewTimer = ( Timer_t * ) pxTimerBuffer; /*lint !e740 !e9087 StaticTimer_t is a pointer to a Timer_t, so guaranteed to be aligned and sized correctly (checked by an assert()), so this is safe. */ + + if( pxNewTimer != NULL ) + { + /* Timers can be created statically or dynamically so note this + timer was created statically in case it is later deleted. The + autoreload bit may get set in prvInitialiseNewTimer(). */ + pxNewTimer->ucStatus = tmrSTATUS_IS_STATICALLY_ALLOCATED; + + prvInitialiseNewTimer( pcTimerName, xTimerPeriodInTicks, uxAutoReload, pvTimerID, pxCallbackFunction, pxNewTimer ); + } + + return pxNewTimer; + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ +/*-----------------------------------------------------------*/ + +static void prvInitialiseNewTimer( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + Timer_t *pxNewTimer ) +{ + /* 0 is not a valid value for xTimerPeriodInTicks. */ + configASSERT( ( xTimerPeriodInTicks > 0 ) ); + + if( pxNewTimer != NULL ) + { + /* Ensure the infrastructure used by the timer service task has been + created/initialised. */ + prvCheckForValidListAndQueue(); + + /* Initialise the timer structure members using the function + parameters. */ + pxNewTimer->pcTimerName = pcTimerName; + pxNewTimer->xTimerPeriodInTicks = xTimerPeriodInTicks; + pxNewTimer->pvTimerID = pvTimerID; + pxNewTimer->pxCallbackFunction = pxCallbackFunction; + vListInitialiseItem( &( pxNewTimer->xTimerListItem ) ); + if( uxAutoReload != pdFALSE ) + { + pxNewTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } +#if TIMER_LEGACY_API /* << EST */ + pxNewTimer->uxAutoReload = uxAutoReload; +#endif + traceTIMER_CREATE( pxNewTimer ); + } +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) +{ +BaseType_t xReturn = pdFAIL; +DaemonTaskMessage_t xMessage; + + configASSERT( xTimer ); + + /* Send a message to the timer service task to perform a particular action + on a particular timer definition. */ + if( xTimerQueue != NULL ) + { + /* Send a command to the timer service task to start the xTimer timer. */ + xMessage.xMessageID = xCommandID; + xMessage.u.xTimerParameters.xMessageValue = xOptionalValue; + xMessage.u.xTimerParameters.pxTimer = xTimer; + + if( xCommandID < tmrFIRST_FROM_ISR_COMMAND ) + { + if( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING ) + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + } + else + { + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, tmrNO_DELAY ); + } + } + else + { + xReturn = xQueueSendToBackFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + } + + traceTIMER_COMMAND_SEND( xTimer, xCommandID, xOptionalValue, xReturn ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + return xReturn; +} +/*-----------------------------------------------------------*/ + +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) +{ + /* If xTimerGetTimerDaemonTaskHandle() is called before the scheduler has been + started, then xTimerTaskHandle will be NULL. */ + configASSERT( ( xTimerTaskHandle != NULL ) ); + return xTimerTaskHandle; +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->xTimerPeriodInTicks; +} +/*-----------------------------------------------------------*/ + +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) +{ +Timer_t * pxTimer = xTimer; + + configASSERT( xTimer ); + taskENTER_CRITICAL(); + { + if( uxAutoReload != pdFALSE ) + { + pxTimer->ucStatus |= tmrSTATUS_IS_AUTORELOAD; + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_AUTORELOAD; + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) +{ +Timer_t * pxTimer = xTimer; +TickType_t xReturn; + + configASSERT( xTimer ); + xReturn = listGET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ) ); + return xReturn; +} +/*-----------------------------------------------------------*/ + +const char * pcTimerGetName( TimerHandle_t xTimer ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +{ +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + return pxTimer->pcTimerName; +} +/*-----------------------------------------------------------*/ + +static void prvProcessExpiredTimer( const TickType_t xNextExpireTime, const TickType_t xTimeNow ) +{ +BaseType_t xResult; +Timer_t * const pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + + /* Remove the timer from the list of active timers. A check has already + been performed to ensure the list is not empty. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* If the timer is an auto reload timer then calculate the next + expiry time and re-insert the timer in the list of active timers. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* The timer is inserted into a list using a time relative to anything + other than the current time. It will therefore be inserted into the + correct list relative to the time this task thinks it is now. */ + if( prvInsertTimerInActiveList( pxTimer, ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ), xTimeNow, xNextExpireTime ) != pdFALSE ) + { + /* The timer expired before it was added to the active timer + list. Reload it now. */ + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + mtCOVERAGE_TEST_MARKER(); + } + + /* Call the timer callback. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); +} +/*-----------------------------------------------------------*/ + +static portTASK_FUNCTION( prvTimerTask, pvParameters ) +{ +TickType_t xNextExpireTime; +BaseType_t xListWasEmpty; + + /* Just to avoid compiler warnings. */ + ( void ) pvParameters; + + #if( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + { + extern void vApplicationDaemonTaskStartupHook( void ); + + /* Allow the application writer to execute some code in the context of + this task at the point the task starts executing. This is useful if the + application includes initialisation code that would benefit from + executing after the scheduler has been started. */ + vApplicationDaemonTaskStartupHook(); + } + #endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + for( ;; ) + { + /* Query the timers list to see if it contains any timers, and if so, + obtain the time at which the next timer will expire. */ + xNextExpireTime = prvGetNextExpireTime( &xListWasEmpty ); + + /* If a timer has expired, process it. Otherwise, block this task + until either a timer does expire, or a command is received. */ + prvProcessTimerOrBlockTask( xNextExpireTime, xListWasEmpty ); + + /* Empty the command queue. */ + prvProcessReceivedCommands(); + } +} +/*-----------------------------------------------------------*/ + +static void prvProcessTimerOrBlockTask( const TickType_t xNextExpireTime, BaseType_t xListWasEmpty ) +{ +TickType_t xTimeNow; +BaseType_t xTimerListsWereSwitched; + + vTaskSuspendAll(); + { + /* Obtain the time now to make an assessment as to whether the timer + has expired or not. If obtaining the time causes the lists to switch + then don't process this timer as any timers that remained in the list + when the lists were switched will have been processed within the + prvSampleTimeNow() function. */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + if( xTimerListsWereSwitched == pdFALSE ) + { + /* The tick count has not overflowed, has the timer expired? */ + if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) + { + ( void ) xTaskResumeAll(); + prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); + } + else + { + /* The tick count has not overflowed, and the next expire + time has not been reached yet. This task should therefore + block to wait for the next expire time or a command to be + received - whichever comes first. The following line cannot + be reached unless xNextExpireTime > xTimeNow, except in the + case when the current timer list is empty. */ + if( xListWasEmpty != pdFALSE ) + { + /* The current timer list is empty - is the overflow list + also empty? */ + xListWasEmpty = listLIST_IS_EMPTY( pxOverflowTimerList ); + } + + vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); + + if( xTaskResumeAll() == pdFALSE ) + { + /* Yield to wait for either a command to arrive, or the + block time to expire. If a command arrived between the + critical section being exited and this yield then the yield + will not cause the task to block. */ + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + } + else + { + ( void ) xTaskResumeAll(); + } + } +} +/*-----------------------------------------------------------*/ + +static TickType_t prvGetNextExpireTime( BaseType_t * const pxListWasEmpty ) +{ +TickType_t xNextExpireTime; + + /* Timers are listed in expiry time order, with the head of the list + referencing the task that will expire first. Obtain the time at which + the timer with the nearest expiry time will expire. If there are no + active timers then just set the next expire time to 0. That will cause + this task to unblock when the tick count overflows, at which point the + timer lists will be switched and the next expiry time can be + re-assessed. */ + *pxListWasEmpty = listLIST_IS_EMPTY( pxCurrentTimerList ); + if( *pxListWasEmpty == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + } + else + { + /* Ensure the task unblocks when the tick count rolls over. */ + xNextExpireTime = ( TickType_t ) 0U; + } + + return xNextExpireTime; +} +/*-----------------------------------------------------------*/ + +static TickType_t prvSampleTimeNow( BaseType_t * const pxTimerListsWereSwitched ) +{ +TickType_t xTimeNow; +PRIVILEGED_DATA static TickType_t xLastTime = ( TickType_t ) 0U; /*lint !e956 Variable is only accessible to one task. */ + + xTimeNow = xTaskGetTickCount(); + + if( xTimeNow < xLastTime ) + { + prvSwitchTimerLists(); + *pxTimerListsWereSwitched = pdTRUE; + } + else + { + *pxTimerListsWereSwitched = pdFALSE; + } + + xLastTime = xTimeNow; + + return xTimeNow; +} +/*-----------------------------------------------------------*/ + +static BaseType_t prvInsertTimerInActiveList( Timer_t * const pxTimer, const TickType_t xNextExpiryTime, const TickType_t xTimeNow, const TickType_t xCommandTime ) +{ +BaseType_t xProcessTimerNow = pdFALSE; + + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xNextExpiryTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + + if( xNextExpiryTime <= xTimeNow ) + { + /* Has the expiry time elapsed between the command to start/reset a + timer was issued, and the time the command was processed? */ + if( ( ( TickType_t ) ( xTimeNow - xCommandTime ) ) >= pxTimer->xTimerPeriodInTicks ) /*lint !e961 MISRA exception as the casts are only redundant for some ports. */ + { + /* The time between a command being issued and the command being + processed actually exceeds the timers period. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxOverflowTimerList, &( pxTimer->xTimerListItem ) ); + } + } + else + { + if( ( xTimeNow < xCommandTime ) && ( xNextExpiryTime >= xCommandTime ) ) + { + /* If, since the command was issued, the tick count has overflowed + but the expiry time has not, then the timer must have already passed + its expiry time and should be processed immediately. */ + xProcessTimerNow = pdTRUE; + } + else + { + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + } + + return xProcessTimerNow; +} +/*-----------------------------------------------------------*/ + +static void prvProcessReceivedCommands( void ) +{ +DaemonTaskMessage_t xMessage; +Timer_t *pxTimer; +BaseType_t xTimerListsWereSwitched, xResult; +TickType_t xTimeNow; + + while( xQueueReceive( xTimerQueue, &xMessage, tmrNO_DELAY ) != pdFAIL ) /*lint !e603 xMessage does not have to be initialised as it is passed out, not in, and it is not used unless xQueueReceive() returns pdTRUE. */ + { + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + { + /* Negative commands are pended function calls rather than timer + commands. */ + if( xMessage.xMessageID < ( BaseType_t ) 0 ) + { + const CallbackParameters_t * const pxCallback = &( xMessage.u.xCallbackParameters ); + + /* The timer uses the xCallbackParameters member to request a + callback be executed. Check the callback is not NULL. */ + configASSERT( pxCallback ); + + /* Call the function. */ + pxCallback->pxCallbackFunction( pxCallback->pvParameter1, pxCallback->ulParameter2 ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* INCLUDE_xTimerPendFunctionCall */ + + /* Commands that are positive are timer commands rather than pended + function calls. */ + if( xMessage.xMessageID >= ( BaseType_t ) 0 ) + { + /* The messages uses the xTimerParameters member to work on a + software timer. */ + pxTimer = xMessage.u.xTimerParameters.pxTimer; + + if( listIS_CONTAINED_WITHIN( NULL, &( pxTimer->xTimerListItem ) ) == pdFALSE ) /*lint !e961. The cast is only redundant when NULL is passed into the macro. */ + { + /* The timer is in a list, remove it. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + + traceTIMER_COMMAND_RECEIVED( pxTimer, xMessage.xMessageID, xMessage.u.xTimerParameters.xMessageValue ); + + /* In this case the xTimerListsWereSwitched parameter is not used, but + it must be present in the function call. prvSampleTimeNow() must be + called after the message is received from xTimerQueue so there is no + possibility of a higher priority task adding a message to the message + queue with a time that is ahead of the timer daemon task (because it + pre-empted the timer daemon task after the xTimeNow value was set). */ + xTimeNow = prvSampleTimeNow( &xTimerListsWereSwitched ); + + switch( xMessage.xMessageID ) + { + case tmrCOMMAND_START : + case tmrCOMMAND_START_FROM_ISR : + case tmrCOMMAND_RESET : + case tmrCOMMAND_RESET_FROM_ISR : + case tmrCOMMAND_START_DONT_TRACE : + /* Start or restart a timer. */ + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + if( prvInsertTimerInActiveList( pxTimer, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, xTimeNow, xMessage.u.xTimerParameters.xMessageValue ) != pdFALSE ) + { + /* The timer expired before it was added to the active + timer list. Process it now. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + traceTIMER_EXPIRED( pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xMessage.u.xTimerParameters.xMessageValue + pxTimer->xTimerPeriodInTicks, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + break; + + case tmrCOMMAND_STOP : + case tmrCOMMAND_STOP_FROM_ISR : + /* The timer has already been removed from the active list. */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + break; + + case tmrCOMMAND_CHANGE_PERIOD : + case tmrCOMMAND_CHANGE_PERIOD_FROM_ISR : + pxTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + pxTimer->xTimerPeriodInTicks = xMessage.u.xTimerParameters.xMessageValue; + configASSERT( ( pxTimer->xTimerPeriodInTicks > 0 ) ); + + /* The new period does not really have a reference, and can + be longer or shorter than the old one. The command time is + therefore set to the current time, and as the period cannot + be zero the next expiry time can only be in the future, + meaning (unlike for the xTimerStart() case above) there is + no fail case that needs to be handled here. */ + ( void ) prvInsertTimerInActiveList( pxTimer, ( xTimeNow + pxTimer->xTimerPeriodInTicks ), xTimeNow, xTimeNow ); + break; + + case tmrCOMMAND_DELETE : + #if ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + { + /* The timer has already been removed from the active list, + just free up the memory if the memory was dynamically + allocated. */ + if( ( pxTimer->ucStatus & tmrSTATUS_IS_STATICALLY_ALLOCATED ) == ( uint8_t ) 0 ) + { + vPortFree( pxTimer ); + } + else + { + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + } + #else + { + /* If dynamic allocation is not enabled, the memory + could not have been dynamically allocated. So there is + no need to free the memory - just mark the timer as + "not active". */ + pxTimer->ucStatus &= ~tmrSTATUS_IS_ACTIVE; + } + #endif /* configSUPPORT_DYNAMIC_ALLOCATION */ + break; + + default : + /* Don't expect to get here. */ + break; + } + } + } +} +/*-----------------------------------------------------------*/ + +static void prvSwitchTimerLists( void ) +{ +TickType_t xNextExpireTime, xReloadTime; +List_t *pxTemp; +Timer_t *pxTimer; +BaseType_t xResult; + + /* The tick count has overflowed. The timer lists must be switched. + If there are any timers still referenced from the current timer list + then they must have expired and should be processed before the lists + are switched. */ + while( listLIST_IS_EMPTY( pxCurrentTimerList ) == pdFALSE ) + { + xNextExpireTime = listGET_ITEM_VALUE_OF_HEAD_ENTRY( pxCurrentTimerList ); + + /* Remove the timer from the list. */ + pxTimer = ( Timer_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxCurrentTimerList ); /*lint !e9087 !e9079 void * is used as this macro is used with tasks and co-routines too. Alignment is known to be fine as the type of the pointer stored and retrieved is the same. */ + ( void ) uxListRemove( &( pxTimer->xTimerListItem ) ); + traceTIMER_EXPIRED( pxTimer ); + + /* Execute its callback, then send a command to restart the timer if + it is an auto-reload timer. It cannot be restarted here as the lists + have not yet been switched. */ + pxTimer->pxCallbackFunction( ( TimerHandle_t ) pxTimer ); + + if( ( pxTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) != 0 ) + { + /* Calculate the reload value, and if the reload value results in + the timer going into the same timer list then it has already expired + and the timer should be re-inserted into the current list so it is + processed again within this loop. Otherwise a command should be sent + to restart the timer to ensure it is only inserted into a list after + the lists have been swapped. */ + xReloadTime = ( xNextExpireTime + pxTimer->xTimerPeriodInTicks ); + if( xReloadTime > xNextExpireTime ) + { + listSET_LIST_ITEM_VALUE( &( pxTimer->xTimerListItem ), xReloadTime ); + listSET_LIST_ITEM_OWNER( &( pxTimer->xTimerListItem ), pxTimer ); + vListInsert( pxCurrentTimerList, &( pxTimer->xTimerListItem ) ); + } + else + { + xResult = xTimerGenericCommand( pxTimer, tmrCOMMAND_START_DONT_TRACE, xNextExpireTime, NULL, tmrNO_DELAY ); + configASSERT( xResult ); + ( void ) xResult; + } + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + + pxTemp = pxCurrentTimerList; + pxCurrentTimerList = pxOverflowTimerList; + pxOverflowTimerList = pxTemp; +} +/*-----------------------------------------------------------*/ + +static void prvCheckForValidListAndQueue( void ) +{ + /* Check that the list from which active timers are referenced, and the + queue used to communicate with the timer service, have been + initialised. */ + taskENTER_CRITICAL(); + { + if( xTimerQueue == NULL ) + { + vListInitialise( &xActiveTimerList1 ); + vListInitialise( &xActiveTimerList2 ); + pxCurrentTimerList = &xActiveTimerList1; + pxOverflowTimerList = &xActiveTimerList2; + + #if( configSUPPORT_STATIC_ALLOCATION == 1 ) + { + /* The timer queue is allocated statically in case + configSUPPORT_DYNAMIC_ALLOCATION is 0. */ + static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + + xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); + } + #else + { + xTimerQueue = xQueueCreate( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, sizeof( DaemonTaskMessage_t ) ); + } + #endif + + #if ( configQUEUE_REGISTRY_SIZE > 0 ) + { + if( xTimerQueue != NULL ) + { + vQueueAddToRegistry( xTimerQueue, "TmrQ" ); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* configQUEUE_REGISTRY_SIZE */ + } + else + { + mtCOVERAGE_TEST_MARKER(); + } + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) +{ +BaseType_t xReturn; +Timer_t *pxTimer = xTimer; + + configASSERT( xTimer ); + + /* Is the timer in the list of active timers? */ + taskENTER_CRITICAL(); + { + if( ( pxTimer->ucStatus & tmrSTATUS_IS_ACTIVE ) == 0 ) + { + xReturn = pdFALSE; + } + else + { + xReturn = pdTRUE; + } + } + taskEXIT_CRITICAL(); + + return xReturn; +} /*lint !e818 Can't be pointer to const due to the typedef. */ +/*-----------------------------------------------------------*/ + +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) +{ +Timer_t * const pxTimer = xTimer; +void *pvReturn; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pvReturn = pxTimer->pvTimerID; + } + taskEXIT_CRITICAL(); + + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) +{ +Timer_t * const pxTimer = xTimer; + + configASSERT( xTimer ); + + taskENTER_CRITICAL(); + { + pxTimer->pvTimerID = pvNewID; + } + taskEXIT_CRITICAL(); +} +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendFromISR( xTimerQueue, &xMessage, pxHigherPriorityTaskWoken ); + + tracePEND_FUNC_CALL_FROM_ISR( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if( INCLUDE_xTimerPendFunctionCall == 1 ) + + BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) + { + DaemonTaskMessage_t xMessage; + BaseType_t xReturn; + + /* This function can only be called after a timer has been created or + after the scheduler has been started because, until then, the timer + queue does not exist. */ + configASSERT( xTimerQueue ); + + /* Complete the message with the function parameters and post it to the + daemon task. */ + xMessage.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage.u.xCallbackParameters.pxCallbackFunction = xFunctionToPend; + xMessage.u.xCallbackParameters.pvParameter1 = pvParameter1; + xMessage.u.xCallbackParameters.ulParameter2 = ulParameter2; + + xReturn = xQueueSendToBack( xTimerQueue, &xMessage, xTicksToWait ); + + tracePEND_FUNC_CALL( xFunctionToPend, pvParameter1, ulParameter2, xReturn ); + + return xReturn; + } + +#endif /* INCLUDE_xTimerPendFunctionCall */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) + { + return ( ( Timer_t * ) xTimer )->uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +#if ( configUSE_TRACE_FACILITY == 1 ) + + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) + { + ( ( Timer_t * ) xTimer )->uxTimerNumber = uxTimerNumber; + } + +#endif /* configUSE_TRACE_FACILITY */ +/*-----------------------------------------------------------*/ + +/* This entire source file will be skipped if the application is not configured +to include software timer functionality. If you want to include software timer +functionality then ensure configUSE_TIMERS is set to 1 in FreeRTOSConfig.h. */ +#endif /* configUSE_TIMERS == 1 */ + + + + diff --git a/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.h b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.h new file mode 100644 index 0000000..a6f9324 --- /dev/null +++ b/Projects/tinyk20_OpenPnP_AutoFeeder/Generated_Code/timers.h @@ -0,0 +1,1296 @@ +/* + * FreeRTOS Kernel V10.2.1 + * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef TIMERS_H +#define TIMERS_H + +#ifndef INC_FREERTOS_H + #error "include FreeRTOS.h must appear in source files before include timers.h" +#endif + +/*lint -save -e537 This headers are only multiply included if the application code +happens to also be including task.h. */ +#include "task.h" +/*lint -restore */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*----------------------------------------------------------- + * MACROS AND DEFINITIONS + *----------------------------------------------------------*/ + +/* IDs for commands that can be sent/received on the timer queue. These are to +be used solely through the macros that make up the public software timer API, +as defined below. The commands that are sent from interrupts must use the +highest numbers as tmrFIRST_FROM_ISR_COMMAND is used to determine if the task +or interrupt version of the queue send function should be used. */ +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + + +/** + * Type by which software timers are referenced. For example, a call to + * xTimerCreate() returns an TimerHandle_t variable that can then be used to + * reference the subject timer in calls to other software timer API functions + * (for example, xTimerStart(), xTimerReset(), etc.). + */ +struct tmrTimerControl; /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +typedef struct tmrTimerControl * TimerHandle_t; + +/* + * Defines the prototype to which timer callback functions must conform. + */ +typedef void (*TimerCallbackFunction_t)( TimerHandle_t xTimer ); + +/* + * Defines the prototype to which functions used with the + * xTimerPendFunctionCallFromISR() function must conform. + */ +typedef void (*PendedFunction_t)( void *, uint32_t ); + +/** + * TimerHandle_t xTimerCreate( const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @return If the timer is successfully created then a handle to the newly + * created timer is returned. If the timer cannot be created (because either + * there is insufficient FreeRTOS heap remaining to allocate the timer + * structures, or the timer period was set to 0) then NULL is returned. + * + * Example usage: + * @verbatim + * #define NUM_TIMERS 5 + * + * // An array to hold handles to the created timers. + * TimerHandle_t xTimers[ NUM_TIMERS ]; + * + * // An array to hold a count of the number of times each timer expires. + * int32_t lExpireCounters[ NUM_TIMERS ] = { 0 }; + * + * // Define a callback function that will be used by multiple timer instances. + * // The callback function does nothing but count the number of times the + * // associated timer expires, and stop the timer once the timer has expired + * // 10 times. + * void vTimerCallback( TimerHandle_t pxTimer ) + * { + * int32_t lArrayIndex; + * const int32_t xMaxExpiryCountBeforeStopping = 10; + * + * // Optionally do something if the pxTimer parameter is NULL. + * configASSERT( pxTimer ); + * + * // Which timer expired? + * lArrayIndex = ( int32_t ) pvTimerGetTimerID( pxTimer ); + * + * // Increment the number of times that pxTimer has expired. + * lExpireCounters[ lArrayIndex ] += 1; + * + * // If the timer has expired 10 times then stop it from running. + * if( lExpireCounters[ lArrayIndex ] == xMaxExpiryCountBeforeStopping ) + * { + * // Do not use a block time if calling a timer API function from a + * // timer callback function, as doing so could cause a deadlock! + * xTimerStop( pxTimer, 0 ); + * } + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start some timers. Starting the timers before the scheduler + * // has been started means the timers will start running immediately that + * // the scheduler starts. + * for( x = 0; x < NUM_TIMERS; x++ ) + * { + * xTimers[ x ] = xTimerCreate( "Timer", // Just a text name, not used by the kernel. + * ( 100 * x ), // The timer period in ticks. + * pdTRUE, // The timers will auto-reload themselves when they expire. + * ( void * ) x, // Assign each timer a unique id equal to its array index. + * vTimerCallback // Each timer calls the same callback when it expires. + * ); + * + * if( xTimers[ x ] == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xTimers[ x ], 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreate( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction ) PRIVILEGED_FUNCTION; +#endif + +/** + * TimerHandle_t xTimerCreateStatic(const char * const pcTimerName, + * TickType_t xTimerPeriodInTicks, + * UBaseType_t uxAutoReload, + * void * pvTimerID, + * TimerCallbackFunction_t pxCallbackFunction, + * StaticTimer_t *pxTimerBuffer ); + * + * Creates a new software timer instance, and returns a handle by which the + * created software timer can be referenced. + * + * Internally, within the FreeRTOS implementation, software timers use a block + * of memory, in which the timer data structure is stored. If a software timer + * is created using xTimerCreate() then the required memory is automatically + * dynamically allocated inside the xTimerCreate() function. (see + * http://www.freertos.org/a00111.html). If a software timer is created using + * xTimerCreateStatic() then the application writer must provide the memory that + * will get used by the software timer. xTimerCreateStatic() therefore allows a + * software timer to be created without using any dynamic memory allocation. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a + * timer into the active state. + * + * @param pcTimerName A text name that is assigned to the timer. This is done + * purely to assist debugging. The kernel itself only ever references a timer + * by its handle, and never by its name. + * + * @param xTimerPeriodInTicks The timer period. The time is defined in tick + * periods so the constant portTICK_PERIOD_MS can be used to convert a time that + * has been specified in milliseconds. For example, if the timer must expire + * after 100 ticks, then xTimerPeriodInTicks should be set to 100. + * Alternatively, if the timer must expire after 500ms, then xPeriod can be set + * to ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than or + * equal to 1000. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the xTimerPeriodInTicks parameter. + * If uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + * + * @param pvTimerID An identifier that is assigned to the timer being created. + * Typically this would be used in the timer callback function to identify which + * timer expired when the same callback function is assigned to more than one + * timer. + * + * @param pxCallbackFunction The function to call when the timer expires. + * Callback functions must have the prototype defined by TimerCallbackFunction_t, + * which is "void vCallbackFunction( TimerHandle_t xTimer );". + * + * @param pxTimerBuffer Must point to a variable of type StaticTimer_t, which + * will be then be used to hold the software timer's data structures, removing + * the need for the memory to be allocated dynamically. + * + * @return If the timer is created then a handle to the created timer is + * returned. If pxTimerBuffer was NULL then NULL is returned. + * + * Example usage: + * @verbatim + * + * // The buffer used to hold the software timer's data structure. + * static StaticTimer_t xTimerBuffer; + * + * // A variable that will be incremented by the software timer's callback + * // function. + * UBaseType_t uxVariableToIncrement = 0; + * + * // A software timer callback function that increments a variable passed to + * // it when the software timer was created. After the 5th increment the + * // callback function stops the software timer. + * static void prvTimerCallback( TimerHandle_t xExpiredTimer ) + * { + * UBaseType_t *puxVariableToIncrement; + * BaseType_t xReturned; + * + * // Obtain the address of the variable to increment from the timer ID. + * puxVariableToIncrement = ( UBaseType_t * ) pvTimerGetTimerID( xExpiredTimer ); + * + * // Increment the variable to show the timer callback has executed. + * ( *puxVariableToIncrement )++; + * + * // If this callback has executed the required number of times, stop the + * // timer. + * if( *puxVariableToIncrement == 5 ) + * { + * // This is called from a timer callback so must not block. + * xTimerStop( xExpiredTimer, staticDONT_BLOCK ); + * } + * } + * + * + * void main( void ) + * { + * // Create the software time. xTimerCreateStatic() has an extra parameter + * // than the normal xTimerCreate() API function. The parameter is a pointer + * // to the StaticTimer_t structure that will hold the software timer + * // structure. If the parameter is passed as NULL then the structure will be + * // allocated dynamically, just as if xTimerCreate() had been called. + * xTimer = xTimerCreateStatic( "T1", // Text name for the task. Helps debugging only. Not used by FreeRTOS. + * xTimerPeriod, // The period of the timer in ticks. + * pdTRUE, // This is an auto-reload timer. + * ( void * ) &uxVariableToIncrement, // A variable incremented by the software timer's callback function + * prvTimerCallback, // The function to execute when the timer expires. + * &xTimerBuffer ); // The buffer that will hold the software timer structure. + * + * // The scheduler has not started yet so a block time is not used. + * xReturned = xTimerStart( xTimer, 0 ); + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timers running as they have already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#if( configSUPPORT_STATIC_ALLOCATION == 1 ) + TimerHandle_t xTimerCreateStatic( const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + const TickType_t xTimerPeriodInTicks, + const UBaseType_t uxAutoReload, + void * const pvTimerID, + TimerCallbackFunction_t pxCallbackFunction, + StaticTimer_t *pxTimerBuffer ) PRIVILEGED_FUNCTION; +#endif /* configSUPPORT_STATIC_ALLOCATION */ + +/** + * void *pvTimerGetTimerID( TimerHandle_t xTimer ); + * + * Returns the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer, and by calling the + * vTimerSetTimerID() API function. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being queried. + * + * @return The ID assigned to the timer being queried. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void *pvTimerGetTimerID( const TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ); + * + * Sets the ID assigned to the timer. + * + * IDs are assigned to timers using the pvTimerID parameter of the call to + * xTimerCreated() that was used to create the timer. + * + * If the same callback function is assigned to multiple timers then the timer + * ID can be used as time specific (timer local) storage. + * + * @param xTimer The timer being updated. + * + * @param pvNewID The ID to assign to the timer. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + */ +void vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ); + * + * Queries a timer to see if it is active or dormant. + * + * A timer will be dormant if: + * 1) It has been created but not started, or + * 2) It is an expired one-shot timer that has not been restarted. + * + * Timers are created in the dormant state. The xTimerStart(), xTimerReset(), + * xTimerStartFromISR(), xTimerResetFromISR(), xTimerChangePeriod() and + * xTimerChangePeriodFromISR() API functions can all be used to transition a timer into the + * active state. + * + * @param xTimer The timer being queried. + * + * @return pdFALSE will be returned if the timer is dormant. A value other than + * pdFALSE will be returned if the timer is active. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is active, do something. + * } + * else + * { + * // xTimer is not active, do something else. + * } + * } + * @endverbatim + */ +BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** + * TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ); + * + * Simply returns the handle of the timer service/daemon task. It it not valid + * to call xTimerGetTimerDaemonTaskHandle() before the scheduler has been started. + */ +TaskHandle_t xTimerGetTimerDaemonTaskHandle( void ) PRIVILEGED_FUNCTION; + +/** + * BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStart() starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerStart() has equivalent functionality + * to the xTimerReset() API function. + * + * Starting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerStart() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerStart() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerStart() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStart() + * to be available. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the start command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStart() was called. xTicksToWait is ignored if xTimerStart() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStart( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerStop() stops a timer that was previously started using either of the + * The xTimerStart(), xTimerReset(), xTimerStartFromISR(), xTimerResetFromISR(), + * xTimerChangePeriod() or xTimerChangePeriodFromISR() API functions. + * + * Stopping a timer ensures the timer is not in the active state. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerStop() + * to be available. + * + * @param xTimer The handle of the timer being stopped. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the stop command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerStop() was called. xTicksToWait is ignored if xTimerStop() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerCreate() API function example usage scenario. + * + */ +#define xTimerStop( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerChangePeriod( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerChangePeriod() changes the period of a timer that was previously + * created using the xTimerCreate() API function. + * + * xTimerChangePeriod() can be called to change the period of an active or + * dormant state timer. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerChangePeriod() to be available. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the change period command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerChangePeriod() was called. xTicksToWait is ignored if + * xTimerChangePeriod() is called before the scheduler is started. + * + * @return pdFAIL will be returned if the change period command could not be + * sent to the timer command queue even after xTicksToWait ticks had passed. + * pdPASS will be returned if the command was successfully sent to the timer + * command queue. When the command is actually processed will depend on the + * priority of the timer service/daemon task relative to other tasks in the + * system. The timer service/daemon task priority is set by the + * configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This function assumes xTimer has already been created. If the timer + * // referenced by xTimer is already active when it is called, then the timer + * // is deleted. If the timer referenced by xTimer is not active when it is + * // called, then the period of the timer is set to 500ms and the timer is + * // started. + * void vAFunction( TimerHandle_t xTimer ) + * { + * if( xTimerIsTimerActive( xTimer ) != pdFALSE ) // or more simply and equivalently "if( xTimerIsTimerActive( xTimer ) )" + * { + * // xTimer is already active - delete it. + * xTimerDelete( xTimer ); + * } + * else + * { + * // xTimer is not active, change its period to 500ms. This will also + * // cause the timer to start. Block for a maximum of 100 ticks if the + * // change period command cannot immediately be sent to the timer + * // command queue. + * if( xTimerChangePeriod( xTimer, 500 / portTICK_PERIOD_MS, 100 ) == pdPASS ) + * { + * // The command was successfully sent. + * } + * else + * { + * // The command could not be sent, even after waiting for 100 ticks + * // to pass. Take appropriate action here. + * } + * } + * } + * @endverbatim + */ + #define xTimerChangePeriod( xTimer, xNewPeriod, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD, ( xNewPeriod ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerDelete() deletes a timer that was previously created using the + * xTimerCreate() API function. + * + * The configUSE_TIMERS configuration constant must be set to 1 for + * xTimerDelete() to be available. + * + * @param xTimer The handle of the timer being deleted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the delete command to be + * successfully sent to the timer command queue, should the queue already be + * full when xTimerDelete() was called. xTicksToWait is ignored if xTimerDelete() + * is called before the scheduler is started. + * + * @return pdFAIL will be returned if the delete command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * + * See the xTimerChangePeriod() API function example usage scenario. + */ +#define xTimerDelete( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_DELETE, 0U, NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ); + * + * Timer functionality is provided by a timer service/daemon task. Many of the + * public FreeRTOS timer API functions send commands to the timer service task + * through a queue called the timer command queue. The timer command queue is + * private to the kernel itself and is not directly accessible to application + * code. The length of the timer command queue is set by the + * configTIMER_QUEUE_LENGTH configuration constant. + * + * xTimerReset() re-starts a timer that was previously created using the + * xTimerCreate() API function. If the timer had already been started and was + * already in the active state, then xTimerReset() will cause the timer to + * re-evaluate its expiry time so that it is relative to when xTimerReset() was + * called. If the timer was in the dormant state then xTimerReset() has + * equivalent functionality to the xTimerStart() API function. + * + * Resetting a timer ensures the timer is in the active state. If the timer + * is not stopped, deleted, or reset in the mean time, the callback function + * associated with the timer will get called 'n' ticks after xTimerReset() was + * called, where 'n' is the timers defined period. + * + * It is valid to call xTimerReset() before the scheduler has been started, but + * when this is done the timer will not actually start until the scheduler is + * started, and the timers expiry time will be relative to when the scheduler is + * started, not relative to when xTimerReset() was called. + * + * The configUSE_TIMERS configuration constant must be set to 1 for xTimerReset() + * to be available. + * + * @param xTimer The handle of the timer being reset/started/restarted. + * + * @param xTicksToWait Specifies the time, in ticks, that the calling task should + * be held in the Blocked state to wait for the reset command to be successfully + * sent to the timer command queue, should the queue already be full when + * xTimerReset() was called. xTicksToWait is ignored if xTimerReset() is called + * before the scheduler is started. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue even after xTicksToWait ticks had passed. pdPASS will + * be returned if the command was successfully sent to the timer command queue. + * When the command is actually processed will depend on the priority of the + * timer service/daemon task relative to other tasks in the system, although the + * timers expiry time is relative to when xTimerStart() is actually called. The + * timer service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // When a key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer. + * + * TimerHandle_t xBacklightTimer = NULL; + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press event handler. + * void vKeyPressEventHandler( char cKey ) + * { + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. Wait 10 ticks for the command to be successfully sent + * // if it cannot be sent immediately. + * vSetBacklightState( BACKLIGHT_ON ); + * if( xTimerReset( xBacklightTimer, 100 ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * } + * + * void main( void ) + * { + * int32_t x; + * + * // Create then start the one-shot timer that is responsible for turning + * // the back-light off if no keys are pressed within a 5 second period. + * xBacklightTimer = xTimerCreate( "BacklightTimer", // Just a text name, not used by the kernel. + * ( 5000 / portTICK_PERIOD_MS), // The timer period in ticks. + * pdFALSE, // The timer is a one-shot timer. + * 0, // The id is not used by the callback so can take any value. + * vBacklightTimerCallback // The callback function that switches the LCD back-light off. + * ); + * + * if( xBacklightTimer == NULL ) + * { + * // The timer was not created. + * } + * else + * { + * // Start the timer. No block time is specified, and even if one was + * // it would be ignored because the scheduler has not yet been + * // started. + * if( xTimerStart( xBacklightTimer, 0 ) != pdPASS ) + * { + * // The timer could not be set into the Active state. + * } + * } + * + * // ... + * // Create tasks here. + * // ... + * + * // Starting the scheduler will start the timer running as it has already + * // been set into the active state. + * vTaskStartScheduler(); + * + * // Should not reach here. + * for( ;; ); + * } + * @endverbatim + */ +#define xTimerReset( xTimer, xTicksToWait ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET, ( xTaskGetTickCount() ), NULL, ( xTicksToWait ) ) + +/** + * BaseType_t xTimerStartFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStart() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being started/restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStartFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStartFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStartFromISR() function. If + * xTimerStartFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the start command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerStartFromISR() is actually called. The timer + * service/daemon task priority is set by the configTIMER_TASK_PRIORITY + * configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then restart the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerStartFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The start command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_START_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerStopFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerStop() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer being stopped. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerStopFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerStopFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerStopFromISR() function. If + * xTimerStopFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the stop command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the timer should be simply stopped. + * + * // The interrupt service routine that stops the timer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - simply stop the timer. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerStopFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The stop command was not executed successfully. Take appropriate + * // action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_STOP_FROM_ISR, 0, ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerChangePeriodFromISR( TimerHandle_t xTimer, + * TickType_t xNewPeriod, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerChangePeriod() that can be called from an interrupt + * service routine. + * + * @param xTimer The handle of the timer that is having its period changed. + * + * @param xNewPeriod The new period for xTimer. Timer periods are specified in + * tick periods, so the constant portTICK_PERIOD_MS can be used to convert a time + * that has been specified in milliseconds. For example, if the timer must + * expire after 100 ticks, then xNewPeriod should be set to 100. Alternatively, + * if the timer must expire after 500ms, then xNewPeriod can be set to + * ( 500 / portTICK_PERIOD_MS ) provided configTICK_RATE_HZ is less than + * or equal to 1000. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerChangePeriodFromISR() writes a message to the + * timer command queue, so has the potential to transition the timer service/ + * daemon task out of the Blocked state. If calling xTimerChangePeriodFromISR() + * causes the timer service/daemon task to leave the Blocked state, and the + * timer service/daemon task has a priority equal to or greater than the + * currently executing task (the task that was interrupted), then + * *pxHigherPriorityTaskWoken will get set to pdTRUE internally within the + * xTimerChangePeriodFromISR() function. If xTimerChangePeriodFromISR() sets + * this value to pdTRUE then a context switch should be performed before the + * interrupt exits. + * + * @return pdFAIL will be returned if the command to change the timers period + * could not be sent to the timer command queue. pdPASS will be returned if the + * command was successfully sent to the timer command queue. When the command + * is actually processed will depend on the priority of the timer service/daemon + * task relative to other tasks in the system. The timer service/daemon task + * priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xTimer has already been created and started. When + * // an interrupt occurs, the period of xTimer should be changed to 500ms. + * + * // The interrupt service routine that changes the period of xTimer. + * void vAnExampleInterruptServiceRoutine( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // The interrupt has occurred - change the period of xTimer to 500ms. + * // xHigherPriorityTaskWoken was set to pdFALSE where it was defined + * // (within this function). As this is an interrupt service routine, only + * // FreeRTOS API functions that end in "FromISR" can be used. + * if( xTimerChangePeriodFromISR( xTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The command to change the timers period was not executed + * // successfully. Take appropriate action here. + * } + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerChangePeriodFromISR( xTimer, xNewPeriod, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_CHANGE_PERIOD_FROM_ISR, ( xNewPeriod ), ( pxHigherPriorityTaskWoken ), 0U ) + +/** + * BaseType_t xTimerResetFromISR( TimerHandle_t xTimer, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * A version of xTimerReset() that can be called from an interrupt service + * routine. + * + * @param xTimer The handle of the timer that is to be started, reset, or + * restarted. + * + * @param pxHigherPriorityTaskWoken The timer service/daemon task spends most + * of its time in the Blocked state, waiting for messages to arrive on the timer + * command queue. Calling xTimerResetFromISR() writes a message to the timer + * command queue, so has the potential to transition the timer service/daemon + * task out of the Blocked state. If calling xTimerResetFromISR() causes the + * timer service/daemon task to leave the Blocked state, and the timer service/ + * daemon task has a priority equal to or greater than the currently executing + * task (the task that was interrupted), then *pxHigherPriorityTaskWoken will + * get set to pdTRUE internally within the xTimerResetFromISR() function. If + * xTimerResetFromISR() sets this value to pdTRUE then a context switch should + * be performed before the interrupt exits. + * + * @return pdFAIL will be returned if the reset command could not be sent to + * the timer command queue. pdPASS will be returned if the command was + * successfully sent to the timer command queue. When the command is actually + * processed will depend on the priority of the timer service/daemon task + * relative to other tasks in the system, although the timers expiry time is + * relative to when xTimerResetFromISR() is actually called. The timer service/daemon + * task priority is set by the configTIMER_TASK_PRIORITY configuration constant. + * + * Example usage: + * @verbatim + * // This scenario assumes xBacklightTimer has already been created. When a + * // key is pressed, an LCD back-light is switched on. If 5 seconds pass + * // without a key being pressed, then the LCD back-light is switched off. In + * // this case, the timer is a one-shot timer, and unlike the example given for + * // the xTimerReset() function, the key press event handler is an interrupt + * // service routine. + * + * // The callback function assigned to the one-shot timer. In this case the + * // parameter is not used. + * void vBacklightTimerCallback( TimerHandle_t pxTimer ) + * { + * // The timer expired, therefore 5 seconds must have passed since a key + * // was pressed. Switch off the LCD back-light. + * vSetBacklightState( BACKLIGHT_OFF ); + * } + * + * // The key press interrupt service routine. + * void vKeyPressEventInterruptHandler( void ) + * { + * BaseType_t xHigherPriorityTaskWoken = pdFALSE; + * + * // Ensure the LCD back-light is on, then reset the timer that is + * // responsible for turning the back-light off after 5 seconds of + * // key inactivity. This is an interrupt service routine so can only + * // call FreeRTOS API functions that end in "FromISR". + * vSetBacklightState( BACKLIGHT_ON ); + * + * // xTimerStartFromISR() or xTimerResetFromISR() could be called here + * // as both cause the timer to re-calculate its expiry time. + * // xHigherPriorityTaskWoken was initialised to pdFALSE when it was + * // declared (in this function). + * if( xTimerResetFromISR( xBacklightTimer, &xHigherPriorityTaskWoken ) != pdPASS ) + * { + * // The reset command was not executed successfully. Take appropriate + * // action here. + * } + * + * // Perform the rest of the key processing here. + * + * // If xHigherPriorityTaskWoken equals pdTRUE, then a context switch + * // should be performed. The syntax required to perform a context switch + * // from inside an ISR varies from port to port, and from compiler to + * // compiler. Inspect the demos for the port you are using to find the + * // actual syntax required. + * if( xHigherPriorityTaskWoken != pdFALSE ) + * { + * // Call the interrupt safe yield function here (actual function + * // depends on the FreeRTOS port being used). + * } + * } + * @endverbatim + */ +#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) xTimerGenericCommand( ( xTimer ), tmrCOMMAND_RESET_FROM_ISR, ( xTaskGetTickCountFromISR() ), ( pxHigherPriorityTaskWoken ), 0U ) + + +/** + * BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * BaseType_t *pxHigherPriorityTaskWoken ); + * + * + * Used from application interrupt service routines to defer the execution of a + * function to the RTOS daemon task (the timer service task, hence this function + * is implemented in timers.c and is prefixed with 'Timer'). + * + * Ideally an interrupt service routine (ISR) is kept as short as possible, but + * sometimes an ISR either has a lot of processing to do, or needs to perform + * processing that is not deterministic. In these cases + * xTimerPendFunctionCallFromISR() can be used to defer processing of a function + * to the RTOS daemon task. + * + * A mechanism is provided that allows the interrupt to return directly to the + * task that will subsequently execute the pended callback function. This + * allows the callback function to execute contiguously in time with the + * interrupt - just as if the callback had executed in the interrupt itself. + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param pxHigherPriorityTaskWoken As mentioned above, calling this function + * will result in a message being sent to the timer daemon task. If the + * priority of the timer daemon task (which is set using + * configTIMER_TASK_PRIORITY in FreeRTOSConfig.h) is higher than the priority of + * the currently running task (the task the interrupt interrupted) then + * *pxHigherPriorityTaskWoken will be set to pdTRUE within + * xTimerPendFunctionCallFromISR(), indicating that a context switch should be + * requested before the interrupt exits. For that reason + * *pxHigherPriorityTaskWoken must be initialised to pdFALSE. See the + * example code below. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + * Example usage: + * @verbatim + * + * // The callback function that will execute in the context of the daemon task. + * // Note callback functions must all use this same prototype. + * void vProcessInterface( void *pvParameter1, uint32_t ulParameter2 ) + * { + * BaseType_t xInterfaceToService; + * + * // The interface that requires servicing is passed in the second + * // parameter. The first parameter is not used in this case. + * xInterfaceToService = ( BaseType_t ) ulParameter2; + * + * // ...Perform the processing here... + * } + * + * // An ISR that receives data packets from multiple interfaces + * void vAnISR( void ) + * { + * BaseType_t xInterfaceToService, xHigherPriorityTaskWoken; + * + * // Query the hardware to determine which interface needs processing. + * xInterfaceToService = prvCheckInterfaces(); + * + * // The actual processing is to be deferred to a task. Request the + * // vProcessInterface() callback function is executed, passing in the + * // number of the interface that needs processing. The interface to + * // service is passed in the second parameter. The first parameter is + * // not used in this case. + * xHigherPriorityTaskWoken = pdFALSE; + * xTimerPendFunctionCallFromISR( vProcessInterface, NULL, ( uint32_t ) xInterfaceToService, &xHigherPriorityTaskWoken ); + * + * // If xHigherPriorityTaskWoken is now set to pdTRUE then a context + * // switch should be requested. The macro used is port specific and will + * // be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - refer to + * // the documentation page for the port being used. + * portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); + * + * } + * @endverbatim + */ +BaseType_t xTimerPendFunctionCallFromISR( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, BaseType_t *pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; + + /** + * BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, + * void *pvParameter1, + * uint32_t ulParameter2, + * TickType_t xTicksToWait ); + * + * + * Used to defer the execution of a function to the RTOS daemon task (the timer + * service task, hence this function is implemented in timers.c and is prefixed + * with 'Timer'). + * + * @param xFunctionToPend The function to execute from the timer service/ + * daemon task. The function must conform to the PendedFunction_t + * prototype. + * + * @param pvParameter1 The value of the callback function's first parameter. + * The parameter has a void * type to allow it to be used to pass any type. + * For example, unsigned longs can be cast to a void *, or the void * can be + * used to point to a structure. + * + * @param ulParameter2 The value of the callback function's second parameter. + * + * @param xTicksToWait Calling this function will result in a message being + * sent to the timer daemon task on a queue. xTicksToWait is the amount of + * time the calling task should remain in the Blocked state (so not using any + * processing time) for space to become available on the timer queue if the + * queue is found to be full. + * + * @return pdPASS is returned if the message was successfully sent to the + * timer daemon task, otherwise pdFALSE is returned. + * + */ +BaseType_t xTimerPendFunctionCall( PendedFunction_t xFunctionToPend, void *pvParameter1, uint32_t ulParameter2, TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +/** + * const char * const pcTimerGetName( TimerHandle_t xTimer ); + * + * Returns the name that was assigned to a timer when the timer was created. + * + * @param xTimer The handle of the timer being queried. + * + * @return The name assigned to the timer specified by the xTimer parameter. + */ +const char * pcTimerGetName( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + +/** + * void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ); + * + * Updates a timer to be either an autoreload timer, in which case the timer + * automatically resets itself each time it expires, or a one shot timer, in + * which case the timer will only expire once unless it is manually restarted. + * + * @param xTimer The handle of the timer being updated. + * + * @param uxAutoReload If uxAutoReload is set to pdTRUE then the timer will + * expire repeatedly with a frequency set by the timer's period (see the + * xTimerPeriodInTicks parameter of the xTimerCreate() API function). If + * uxAutoReload is set to pdFALSE then the timer will be a one-shot timer and + * enter the dormant state after it expires. + */ +void vTimerSetReloadMode( TimerHandle_t xTimer, const UBaseType_t uxAutoReload ) PRIVILEGED_FUNCTION; + +/** + * TickType_t xTimerGetPeriod( TimerHandle_t xTimer ); + * + * Returns the period of a timer. + * + * @param xTimer The handle of the timer being queried. + * + * @return The period of the timer in ticks. + */ +TickType_t xTimerGetPeriod( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/** +* TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ); +* +* Returns the time in ticks at which the timer will expire. If this is less +* than the current tick count then the expiry time has overflowed from the +* current time. +* +* @param xTimer The handle of the timer being queried. +* +* @return If the timer is running then the time in ticks at which the timer +* will next expire is returned. If the timer is not running then the return +* value is undefined. +*/ +TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; + +/* + * Functions beyond this part are not part of the public API and are intended + * for use by the kernel only. + */ +BaseType_t xTimerCreateTimerTask( void ) PRIVILEGED_FUNCTION; +BaseType_t xTimerGenericCommand( TimerHandle_t xTimer, const BaseType_t xCommandID, const TickType_t xOptionalValue, BaseType_t * const pxHigherPriorityTaskWoken, const TickType_t xTicksToWait ) PRIVILEGED_FUNCTION; + +#if( configUSE_TRACE_FACILITY == 1 ) + void vTimerSetTimerNumber( TimerHandle_t xTimer, UBaseType_t uxTimerNumber ) PRIVILEGED_FUNCTION; + UBaseType_t uxTimerGetTimerNumber( TimerHandle_t xTimer ) PRIVILEGED_FUNCTION; +#endif + +#ifdef __cplusplus +} +#endif +#endif /* TIMERS_H */ + + + +